Copy link to clipboard
Copied
There are 10 spaces after 1, and the width of bounds is 1814
After replacing the last space in the line where the number 1 is located with X, the bounds width becomes 2043
My question is how to get the width and height of the text layer including the trailing space?
Copy link to clipboard
Copied
Duplicate the layer.
Convert to paths or rasterize.
Get the layer bounds.
Delete the temporary duped layer.
But this will not help with "white space"... You would need to replace the word spaces with a visible character of the equivalent space. Or perhaps put a pipe character or dot at the end and remove this from the calculation, similar to the X.
Edit: does an underscore or strike through work with the white space?
Copy link to clipboard
Copied
All the solutions you suggested require modifying the PSD first, then reading the bounds, and finally restoring. This is too cumbersome. I hope to read some properties, then calculate, and finally get the bounds.
Copy link to clipboard
Copied
Sometimes such things are necessary, but you are correct, in this case they aren't needed. I did find that applying an underscore or strikethrough to the characters does include white space:
Copy link to clipboard
Copied
The following code implements: saving the original text, replacing the space at the end of each line with x and getting the width, and restoring the original text. However, when "layer.textItem.contents = resultString;", the font is missing and a pop-up box will block program execution.
var doc = app.activeDocument;
var layer = doc.activeLayer;
// prompt("层id", layer.id)
if (layer.kind == LayerKind.TEXT) {
// 保存原始文本
var originalText = layer.textItem.contents;
// 提取边界框的各个部分
getBounds(layer.bounds);
var resultString = replaceProcess(originalText)
alert(resultString);
// 设置虚拟字符到文本层
layer.textItem.contents = resultString;
// 提取边界框的各个部分
getBounds(layer.bounds);
// 恢复原始文本
layer.textItem.contents = originalText;
// 提取边界框的各个部分
getBounds(layer.bounds);
} else {
alert("请先选择一个文本图层。");
}
function replaceProcess(originalText) {
// 使用正则表达式匹配任意形式的换行符,将字符串分割成多行
// 同时保留换行符
var lines = [];
var lastIndex = 0;
var match;
// ps貌似只认\r才换行,所以这里列出所有换行
var regex = /(\r\n|\r|\n)/g;
// 找到所有换行符的位置
while ((match = regex.exec(originalText)) !== null) {
lines.push(originalText.slice(lastIndex, match.index)); // 保存每行文本
lines.push(match[0]); // 保存换行符
lastIndex = regex.lastIndex;
}
// 添加最后一段文本(无换行符的文本)
lines.push(originalText.slice(lastIndex));
// 处理每一段,替换结尾的空格为 "a"
for (var i = 0; i < lines.length; i++) {
// 仅处理文本部分,跳过换行符部分
if (lines[i] !== "\r\n" && lines[i] !== "\r" && lines[i] !== "\n") {
// \s可以匹配空白字符,空格、全角空格、tab等
lines[i] = lines[i].replace(/\s$/, "X");
}
}
// 将处理后的行合并回完整的字符串
return lines.join('');
}
function getBounds(bounds) {
var left = bounds[0].as('px');
var top = bounds[1].as('px');
var right = bounds[2].as('px');
var bottom = bounds[3].as('px');
// 计算宽度和高度
var width = right - left;
var height = bottom - top;
// 输出边界框信息
alert("Layer Bounds:\n" +
"Left: " + left + " px\n" +
"Top: " + top + " px\n" +
"Right: " + right + " px\n" +
"Bottom: " + bottom + " px\n" +
"Width: " + width + " px\n" +
"Height: " + height + " px");
}
Initial Width
Replace the last space in each line with X
After replacing x, the width becomes wider
Restore to original text, width becomes initial width
Copy link to clipboard
Copied
Can you provide a sample file (feel free to trash all the other layers)?
Copy link to clipboard
Copied
Copy link to clipboard
Copied
// type layer bounds;
// based on code by michael l hale;
// 2024, use it at your own risk;
if (app.documents.length > 0) {
var ref = new ActionReference();
ref.putProperty(stringIDToTypeID("property"), stringIDToTypeID('textKey'));
ref.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var layerDesc = executeActionGet(ref);
var textDesc = layerDesc.getObjectValue(stringIDToTypeID('textKey'));
var theBounds = textDesc.getObjectValue(stringIDToTypeID("bounds"));
var theWidth = Number(theBounds.getUnitDoubleValue(stringIDToTypeID("right"))) - Number(theBounds.getUnitDoubleValue(stringIDToTypeID("left")));
var theHeight = Number(theBounds.getUnitDoubleValue(stringIDToTypeID("bottom"))) - Number(theBounds.getUnitDoubleValue(stringIDToTypeID("top")));
var thePoint = textDesc.getObjectValue(stringIDToTypeID("textClickPoint"));
pointH = thePoint.getUnitDoubleValue(stringIDToTypeID("horizontal"));
pointV = thePoint.getUnitDoubleValue(stringIDToTypeID("vertical"));
var theBounds = checkDesc2 (theBounds);
alert ("\n\nthe width "+theWidth+"\nthe height "+theHeight+"\n\nbounds\n"+theBounds)
};
////// based on code by michael l hale //////
function checkDesc2 (theDesc, theAlert) {
var c = theDesc.count;
var str = '';
for(var i=0;i<c;i++){ //enumerate descriptor's keys
str = str + 'Key '+i+' = '+typeIDToStringID(theDesc.getKey(i))+': '+theDesc.getType(theDesc.getKey(i))+'\n'+getValues (theDesc, i)+'\n';
};
if (theAlert == true) {alert("desc\n\n"+str);
return};
return str
};
////// check //////
function getValues (theDesc, theNumber) {
switch (theDesc.getType(theDesc.getKey(theNumber))) {
case DescValueType.ALIASTYPE:
return theDesc.getPath(theDesc.getKey(theNumber));
break;
case DescValueType.BOOLEANTYPE:
return theDesc.getBoolean(theDesc.getKey(theNumber));
break;
case DescValueType.CLASSTYPE:
return theDesc.getClass(theDesc.getKey(theNumber));
break;
case DescValueType.DOUBLETYPE:
return theDesc.getDouble(theDesc.getKey(theNumber));
break;
case DescValueType.ENUMERATEDTYPE:
return (typeIDToStringID(theDesc.getEnumerationValue(theDesc.getKey(theNumber)))+"_"+typeIDToStringID(theDesc.getEnumerationType(theDesc.getKey(theNumber))));
break;
case DescValueType.INTEGERTYPE:
return theDesc.getInteger(theDesc.getKey(theNumber));
break;
case DescValueType.LISTTYPE:
return theDesc.getList(theDesc.getKey(theNumber));
break;
case DescValueType.OBJECTTYPE:
return (theDesc.getObjectValue(theDesc.getKey(theNumber))+"_"+typeIDToStringID(theDesc.getObjectType(theDesc.getKey(theNumber))));
break;
case DescValueType.RAWTYPE:
return theDesc.getReference(theDesc.getData(theNumber));
break;
case DescValueType.REFERENCETYPE:
return theDesc.getReference(theDesc.getKey(theNumber));
break;
case DescValueType.STRINGTYPE:
return theDesc.getString(theDesc.getKey(theNumber));
break;
case DescValueType.UNITDOUBLE:
return (theDesc.getUnitDoubleValue(theDesc.getKey(theNumber))+"_"+typeIDToStringID(theDesc.getUnitDoubleType(theDesc.getKey(theNumber))));
break;
default:
break;
};
};
Copy link to clipboard
Copied
The left and top values of "doc.activeLayer.bounds" are inconsistent with the left and top values in the above code. Why is this?
Copy link to clipboard
Copied
The bounds of the Layer itself are determined by the actual area of the letter/s.
The textKey’s bounds are not, so they also include spaces that have no atcual area. (edited)
Copy link to clipboard
Copied
Thank you very much for sharing, I understand
Copy link to clipboard
Copied
The Bounds of the POINTTEXT layer does not contain space characters
My question is how to get the width and height of the text layer including the trailing space?
Spaces do not have a consistent width. Some spaces may be wider while others are narrower.
I was about to suggest a non-breaking space (which has a consistent width), but when I looked it up I found that Photoshop does not support them. Photoshop is primarily an image editor with very limited text controls. You might make a feature request to the product developers if you are not able to use a page layout application for your project.
Although you did not ask, pay attention to the alignment of your numbers, which are all over the place.
Jane
Copy link to clipboard
Copied
Thank you very much for your reply