How to get TextItem position, width and height

Community Beginner ,
Apr 21, 2021 Apr 21, 2021

Copy link to clipboard

Copied

Hello there, 

I do have a question for Photoshop Scripting: 
I want to extract information about TextItems, like width, height, x- and y-position (as well as the size). But it seems like it doesn't work that way it did for an ArtLayer. Can you help me get it right? 

 if (layer.kind == LayerKind.TEXT){
        

        //now we need to do the same thing for a TextLayer
        //I just want following in seperate variables, because of long terms otherwise  
        var textContent = layer.textItem.contents;
        var textSize = layer.textItem.size; 
         var textFont = layer.textItem.font; 
        var textColor = layer.textItem.color.rgb.hexValue;
        //now a new string like above to save it later in main string
        //here is some kind of copy and paste of the string above 
        var str3 = "\tText{\n"
        + "\t\tid: " + layer.name.toLowerCase() +"\n"
        + "\t\ttext: qsTr(\"" + textContent +"\")\n"
        + "\t\tx: " + layer.bounds[0].value +"\n"
        + "\t\ty: " + layer.bounds[1].value + "\n"
        + "\t\tz: " + (i-1) + "\n"
        + "\t\twidth: " + layer.textItem.width + "\n"
        + "\t\theight: " + layer.textItem.height + "\n"
        + "\t\tfont.family: \"" + textFont + "\"\n"
        + "\t\tcolor: \"#" +textColor+"\"\n" 
        + "\t\tfont.pointSize: " + textSize + "\n"
        + "\t\tvisible: " + isVisible + "\n"
        + "\t}" 
        + "\n\n";
        str += str3; 
        
    }; 
}; 

 

The rulerUnits are set to Units.PIXELS, but the size doesn't change if I set it to points (at least its not the right value either way). 

 

Kind regards, 

Senira

 

TOPICS
Actions and scripting, Import and export, Problem or error

Views

91

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Apr 21, 2021 Apr 21, 2021

Copy link to clipboard

Copied

First of all you need access layer, not by layer, but: activeDocument.activeLayer

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Apr 21, 2021 Apr 21, 2021

Copy link to clipboard

Copied

LATEST

I already did this before. I can send you the whole code, this might be more helpful: 

function docCheck(){
    if (!documents.length){
        alert("There are no open documents.\nPlease open a document and try again"); 
        return -1; 
    };
}; 
docCheck(); 

//save original rules and settings since I don't want to change any settings out of the script 
//setting ruler units to pixels, since that is needed for the Qt simulation 
var originalRulerUnits = preferences.rulerUnits; 
preferences.rulerUnits = Units.PIXELS; 

//setting some basic variables and saving width, height and path of the document for later 
var docRef = activeDocument; 
var docWidth = docRef.width.value; 
var docHeight = docRef.height.value; 
var FilePath = docRef.fullName.path + "/"; 

//traverse through all layers 
//but do it reverse for easier programming in Qt later on 
//make it as a function, so we can pass on everything later on 
//so I can stack them from bottom to top most element 
//need ftn here to collect every layer information later on 
//need to define stackorder before this function 🙂 
var stackorder = 0; 

traverseLayers = function (doc, ftn, reverse) {
    function _traverse(doc, layers, ftn, reverse) {
      var ok = true;
      for (var i = 1; i <= layers.length && ok != false; i++) {
        var index = (reverse == true) ? layers.length - i : i - 1;
        var layer = layers[index];
        if (layer.typename == "LayerSet") {
          ok = _traverse(doc, layer.layers, ftn, reverse);
        } else {
          stackorder = stackorder + 1;
          ok = ftn(doc, layer, stackorder);
        }
      }
      return ok;
    };
    return _traverse(doc, doc.layers, ftn, reverse);
  };
//now I need a function to collect all information needed 
//in a string 

//so first step is to initialize a string with the import statements 
//needed in the .qml file in order to run it in Qt5.5
//and the root element, which will be a window 
//with the same dimensions as the document has 
str =   "import QtQuick 2.0\n"
  + "import QtQuick.Window 2.0\n"

  //create a commentary line with the name of the psd file
  //and leave an empty line between import statements
  //this commentary and the root element   
  
  + "\n" + "// psd name: " + docRef.name + "\n\n"
  
  //now we create the root element called item 
  //for a better "look" indent the attributes of the elements
  +"Item {\n\n";
   

//create the function which collects the information and 
//creates the string for each layer    

function layerInformation(doc, layer, i){
    //check if layer is visible
    var isVisible = layer.visible; 
    //get layer width, heigth and position 
    layerWidth = layer.bounds[2].value - layer.bounds[0].value; 
    layerHeight = layer.bounds[3].value - layer.bounds[1].value; 
    //to get position in (x,y) format, I need one more variable 
    //I don't need the position in an (x,y) format anymore 
    layerPosition = layer.bounds[0].value + "," + layer.bounds[1].value; 
    //differentiate between ArtLayer and Text Layer 
    //because I need to extract more information out of a TextLayer 
    
    if (layer.kind != LayerKind.TEXT){
        //for each layer, which is not an ArtLayer
        //I want to create a Rectangle Element which is a child of the root element 
        //with no further connections to the other created elements in this string 
        //It is widely used and it fits the extracted data (which are the 
        //bound dimensions with the bound describing a rectanglular shape)
        //and again for the "looks", I will indent them 
        var str2 = "\tRectangle {\n"
        + "\t\tid: " + layer.name.toLowerCase() +"\n" //id needs to be all lowercase letters for qml 
        + "\t\tx: " + layer.bounds[0].value +"\n"
        + "\t\ty: " + layer.bounds[1].value +"\n"
        + "\t\tz: " + (i-1) + "\n"
        + "\t\twidth: " + layerWidth + "\n"
        + "\t\theight: " + layerHeight + "\n"
        + "\t\tvisible: " + isVisible + "\n"
        + "\t\tcolor: " + "\"transparent\"" + "\n"
        + "\t}"
        +"\n\n";

        //save new information in string, so we can save it later on 
        str += str2; 
        }; 
        
        //else didn't worked, so here comes another if statement 
        //for the text layers which need slightly different information 
    
        if (layer.kind == LayerKind.TEXT){
        

        //now we need to do the same thing for a TextLayer
        //I just want following in seperate variables, because of long terms otherwise  
        var textContent = layer.textItem.contents;
        var textSize = layer.textItem.size; 
         var textFont = layer.textItem.font; 
        var textColor = layer.textItem.color.rgb.hexValue;
        //now a new string like above to save it later in main string
        //here is some kind of copy and paste of the string above 
        var str3 = "\tText{\n"
        + "\t\tid: " + layer.name.toLowerCase() +"\n"
        + "\t\ttext: qsTr(\"" + textContent +"\")\n"
        + "\t\tx: " + layer.bounds[0].value +"\n"
        + "\t\ty: " + layer.bounds[1].value + "\n"
        + "\t\tz: " + (i-1) + "\n"
        + "\t\twidth: " + layer.textItem.width + "\n"
        + "\t\theight: " + layer.textItem.height + "\n"
        + "\t\tfont.family: \"" + textFont + "\"\n"
        + "\t\tcolor: \"#" +textColor+"\"\n" 
        + "\t\tfont.pointSize: " + textSize + "\n"
        + "\t\tvisible: " + isVisible + "\n"
        + "\t}" 
        + "\n\n";
        str += str3; 
        
    }; 
}; 

//now activate the functions with everything needed  
traverseLayers(docRef, layerInformation, true); 

//now save all gathered information in a file
var csvFile = new File(FilePath.toString().match(/([^\.]+)/)[1] + docRef.name.match(/([^\.]+)/)[1] + ".qml");
csvFile.open('w');
csvFile.writeln(str + "}");
csvFile.close();

//set original ruler settings 
preferences.rulerUnits = originalRulerUnits; 

//alert, that everything finished well 🙂 
alert ("Operation complete!" + "\n" + "Required data were successfully exported to:" + "\n" + "\n" + FilePath.toString().match(/([^\.]+)/)[1] + docRef.name.match(/([^\.]+)/)[1] + ".qml")


I got inspired by some other code I found here (https://community.adobe.com/t5/photoshop/export-co-ordinates-layer-bounds/m-p/4420832).

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines