使用PSD.rb gem无法获取PSD文件准确文本框边界求助
获取PSD.rb中准确文本框边界的解决方案
我之前也碰到过一模一样的问题!psd.rb默认返回的确实是文本内容的最小包围盒,而不是Photoshop里手动设置的文本框实际尺寸。结合对PSD文件格式的了解,这里有几个可行的思路可以尝试解决:
1. 从文本层的Engine Data中提取实际文本框
PSD的文本层会把样式和布局数据存在engine_data里,其中就包含了文本框的原始矩形信息。你可以尝试遍历这部分数据来提取:
# 先找到目标文本层 text_layer = psd.descendant_layers.find { |layer| layer.is_text? } # 解析Engine Data中的文本框信息 engine_data = text_layer.text[:engine_data] style_sheet_data = engine_data.dig(:StyleRun, :RunArray, 0, :StyleSheet, :StyleSheetData) if style_sheet_data && style_sheet_data['TxtBx'] # 文本框坐标通常是[x1, y1, x2, y2]格式 x1, y1, x2, y2 = style_sheet_data['TxtBx']['Rectangle'] actual_width = x2 - x1 actual_height = y2 - y1 puts "实际文本框:x=#{x1}, y=#{y1}, 宽=#{actual_width}, 高=#{actual_height}" end
注意:不同Photoshop版本保存的键名可能略有差异,建议先打印style_sheet_data的完整内容,确认具体的键路径。
2. 直接解析PSD的TySh附加信息
如果Engine Data里找不到,还可以读取文本层的TySh(Text Shape)附加信息,这是PSD规范中专门存储文本框形状的标记:
text_layer = psd.descendant_layers.find { |layer| layer.is_text? } tysh_data = text_layer.additional_info['TySh'] if tysh_data # 跳过前4字节的版本号,解析后续的4个32位浮点数(对应矩形的x1,y1,x2,y2) rect_coords = tysh_data[4..-1].unpack('f4') x1, y1, x2, y2 = rect_coords puts "实际文本框矩形:[#{x1}, #{y1}, #{x2}, #{y2}]" end
这里可以参考Adobe官方的PSD文件格式规范,确保字节解析的顺序和格式正确。
3. 扩展psd.rb的功能(长期解决方案)
既然官方issue还没解决,你可以自己fork psd.rb仓库,给文本层类添加一个获取实际文本框的方法:
# 在lib/psd/text.rb中添加方法 class PSD class Text def actual_text_box # 先尝试从Engine Data提取 engine_data = self[:engine_data] style_sheet_data = engine_data.dig(:StyleRun, :RunArray, 0, :StyleSheet, :StyleSheetData) if style_sheet_data&.dig('TxtBx', 'Rectangle') return style_sheet_data['TxtBx']['Rectangle'] end # fallback到解析TySh数据 tysh_data = layer.additional_info['TySh'] return tysh_data[4..-1].unpack('f4') if tysh_data nil end end end
之后就可以直接通过text_layer.text.actual_text_box获取准确的文本框坐标了。
这些方法的核心是直接读取PSD中存储的原始文本框数据,而不是依赖psd.rb默认计算的最小包围盒。建议先打印出文本层的engine_data和additional_info内容,根据你的PSD版本调整具体的解析逻辑。
内容的提问来源于stack exchange,提问作者Sanjith
相关产品推荐
相关产品推荐

