场景:psd文本图层,支持用户自定义多行内容文本替换。
遇到问题:psd解析图层文字更新,只支持1个文本\r。
示例代码:
public static void main(String[] args) {
License license = new License();
String licFileDir = “E:\mysite\openproj\Aspose.PSD-for-Java\Examples\src\main\resources\Lic\Aspose.Total.Product.Family.lic”;
license.setLicense(licFileDir);
String dataDir = “E:\mysite\openproj\Aspose.PSD-for-Java\Examples\src\main\resources\PSD\”;
String sourceFileName = dataDir+ “6d006ea3baa81d8cba9f25ce56a2c970.psd”;
String exportPath = dataDir+ “nvwangNewUpdateText.png”;
PsdLoadOptions loadOptions = new PsdLoadOptions();
PsdImage image =(PsdImage) Image.load(sourceFileName,loadOptions);
for(int i=0; i < image.getLayers().length; i++ )
{
Layer layer = (Layer) image.getLayers()[i];
if (i == 11 && image.getLayers()[i] instanceof TextLayer)
{
TextLayer textLayer = (TextLayer)image.getLayers()[i];
Point leftTopCoordinate = new Point();
leftTopCoordinate.setX(textLayer.getLeft());
leftTopCoordinate.setY(textLayer.getTop());
System.out.println(“Left:” + textLayer.getLeft());
System.out.println(“Top:” + textLayer.getTop());
System.out.println(textLayer.getText());
textLayer.updateText(“靠你就是我\r我的\r你的”, leftTopCoordinate, textLayer.getFont().getSize(), textLayer.getTextColor());
}
}
PngOptions options = new PngOptions();
options.setColorType(PngColorType.TruecolorWithAlpha);
image.save(exportPath,options);
}
运行结果:
image.png (44.3 KB)
实际期房:希望支持多行文本内容替换。
@jsczxielong
能否请您共享源PSD文件,我们可以将其用于验证问题。
源文件:nvwangcopy.zip (118.8 KB)
@jsczxielong
我在问题跟踪系统中创建了一个ID为PSDJAVA-324的问题,以进一步调查和解决该问题。 该线程已与问题联系在一起,因此一旦问题解决,您可能会收到通知。
可否给个具体的修复时间点?另外,若修复OK,是否会以新版本jar的方式解决修复?产品上线紧急,忘加急处理,另外,好跟进商务合同购买事宜。
文本层支持多行不限长度的字体修改,麻烦优先紧急帮忙处理,此块直接影响产品的上线以及服务的购买等商务事宜。
@jsczxielong
我能理解你的紧迫性。 常规支持论坛中记录的问题将按照先到先得的原则进行调查和解决。 如果您想加快问题解决过程,可以考虑使用 付费支持 选项,这可能会对您有所帮助。
为了解决多行问题,您可以使用ITextPortion API。 UpdateText是一种旧方法,它有很多局限性。 它只能用于最简单的情况。 对于您的情况,您需要使用ITextPortion API。
1 Like
你好,已尝试使用ITextPortion Api,有两种方式实现,一种是直接获取textData.producePortion().setText修改文本,也是报同样的错误。另一种是按您推荐的API地址,创建新的ITextPortion,但是无法做到直接修改原文本层的文字替换,因为没有找到相关的setPoint(x,y)。
源代码:
public static void main(String[] args) throws FileNotFoundException {
License license = new License();
String licFileDir = “E:\mysite\openproj\Aspose.PSD-for-Java\Examples\src\main\resources\Lic\Aspose.Total.Product.Family.lic”;
license.setLicense(licFileDir);
String dataDir = "E:\\mysite\\openproj\\Aspose.PSD-for-Java\\Examples\\src\\main\\resources\\PSD\\";
String sourceFileName = dataDir + "6d006ea3baa81d8cba9f25ce56a2c970.psd";
String exportPath = dataDir + "nvwangNewRemove.png";
PsdLoadOptions loadOptions = new PsdLoadOptions();
PsdImage image =(PsdImage) Image.load(sourceFileName,loadOptions);
for(int i=0; i < image.getLayers().length; i++ )
{
if (i == 10 && image.getLayers()[i] instanceof TextLayer)
{
TextLayer textLayer = (TextLayer)image.getLayers()[i];
IText textData = textLayer.getTextData();
System.out.println("textData producePortion text:"+textData.producePortion().getText());
//方案一.直接获取producePortion对象修改文本:报错Line break '\r' character can be only in the end of text
textData.producePortion().setText("靠你就是我就\r我的\r你的");
/*ITextStyle defaultStyle = textData.producePortion().getStyle();
defaultStyle.setFillColor(textLayer.getTextColor());
defaultStyle.setFontSize(textLayer.getFont().getSize());
ITextParagraph defaultParagraph = textData.producePortion().getParagraph();
textData.getItems()[1].getStyle().setStrikethrough(true);
ITextPortion[] newTextPortions = textData.producePortions(new String[] {
"E=mc", "2\r", "Bold", "Italic\r", "Lowercasetext" },
defaultStyle, defaultParagraph);
newTextPortions[0].getStyle().setUnderline(true); // edit text style of "E=mc"
newTextPortions[1].getStyle().setFontBaseline(FontBaseline.Superscript); // edit text style of "2\r"
newTextPortions[2].getStyle().setFauxBold(true); // edit text style of "Bold"
newTextPortions[3].getStyle().setFauxItalic(true); // edit text style of "Italic\r"
newTextPortions[3].getStyle().setBaselineShift(-25); // edit text style of "Italic\r"
newTextPortions[4].getStyle().setFontCaps(FontCaps.SmallCaps); // edit text style of "Lowercasetext"
for (ITextPortion newTextPortion : newTextPortions)
{
textData.addPortion(newTextPortion);
}
textData.updateLayerData();*/
}
}
PngOptions options = new PngOptions();
options.setColorType(PngColorType.TruecolorWithAlpha);
image.save(exportPath,options);
}
第一种方式:输出结果:
image.png (30.6 KB)
第二种方式:输出结果:
image.jpg (38.8 KB)
期望结果:直接修改原文本层的文字内容。
psd:文件:
nvwangJy.zip (2.6 MB)
恩,产品第一阶段,就剩下多换行文本的替换以及源psdImage对象序列化(待验证);若这两种最基本的要求解决了,我们就要走商务,购买付费技术支持了,因后期产品个性化需求迭代较多,付费技术支持才能满足。谢谢
@jsczxielong
如果我是对的,您的意思是说没有选择为TextPortion设置x,y的选项。 您能否分享所获得的结果和所需的输出。 我们将尽力解决这一问题。
0.场景需求:
文本层,文字支持多行不限长度内容替换(原字体、样式等保留,说白了就是直接modify/update文字内容)。
1.源代码:
public static void main(String[] args) throws FileNotFoundException
{
License license = new License();
String licFileDir = "E:\\mysite\\openproj\\Aspose.PSD-for-Java\\Examples\\src\\main\\resources\\Lic\\Aspose.Total.Product.Family.lic";
license.setLicense(licFileDir);
String dataDir = "E:\\mysite\\openproj\\Aspose.PSD-for-Java\\Examples\\src\\main\\resources\\PSD\\";
String sourceFileName = dataDir + "nvwangJy.psd";
String exportPath = dataDir + "nvwangNewITextPortion.png";
PsdLoadOptions loadOptions = new PsdLoadOptions();
//Try this
loadOptions.setLoadEffectsResource(true);
PsdImage image =(PsdImage) Image.load(sourceFileName,loadOptions);
for(int i=0; i < image.getLayers().length; i++ )
{
Layer layer = (Layer) image.getLayers()[i];
System.out.println(i + "DisplayName:" + layer.getDisplayName() + "name:" + layer.getName());
if (i == 11 && image.getLayers()[i] instanceof TextLayer)
{
TextLayer textLayer = (TextLayer)image.getLayers()[i];
IText textData = textLayer.getTextData();
//System.out.println("textData producePortion text:"+textData.producePortion().getText());
//方案一.直接获取producePortion对象修改文本:报错Line break '\r' character can be only in the end of text
//textData.producePortion().setText("靠你就是我的你的");
//方案二.创建新ITextPortion
ITextStyle defaultStyle = textData.producePortion().getStyle();
defaultStyle.setFillColor(textLayer.getTextColor());
defaultStyle.setFontSize(textLayer.getFont().getSize());
ITextParagraph defaultParagraph = textData.producePortion().getParagraph();
textData.getItems()[1].getStyle().setStrikethrough(true);
ITextPortion[] newTextPortions = textData.producePortions(new String[] {
"靠Apose官方你就赢", "\r", "靠自己你最多只会玩", "\r", "靠自己就Win" },
defaultStyle, defaultParagraph);
newTextPortions[0].getStyle().setUnderline(true); // edit text style of "E=mc"
newTextPortions[1].getStyle().setFontBaseline(FontBaseline.Superscript); // edit text style of "2\r"
newTextPortions[2].getStyle().setFauxBold(true); // edit text style of "Bold"
newTextPortions[3].getStyle().setFauxItalic(true); // edit text style of "Italic\r"
newTextPortions[3].getStyle().setBaselineShift(-25); // edit text style of "Italic\r"
newTextPortions[4].getStyle().setFontCaps(FontCaps.SmallCaps); // edit text style of "Lowercasetext"
for (ITextPortion newTextPortion : newTextPortions)
{
textData.addPortion(newTextPortion);
}
textData.updateLayerData();
}
}
PngOptions options = new PngOptions();
options.setColorType(PngColorType.TruecolorWithAlpha);
image.save(exportPath,options);
}
2.源psd文件:
nvwangJy.zip (2.6 MB)
3.源psd文件png图:
nvwangJy.jpg (303.0 KB)
4.期望结果:
nvwangJyExpect.jpg (302.1 KB)
5.实际输出结果:
nvwangNewITextPortion.jpg (351.7 KB)
6.看出需求,希望一步到位输出想要的结果的源代码,OK?
@jsczxielong
您可能需要使用以下代码替换文本以获取所需的输出。 但是,它似乎并没有替换文本并创建空白图像。 我们正在进一步验证这一点,并将尽快与您分享反馈。
public static void ReplaceMultilineText3() throws FileNotFoundException
{
String dataDir ="//Users//mudassirkhan//Downloads//";
String sourceFileName = dataDir + "nvwangJy.psd";
String exportPath = dataDir + "Mudassir3TextUpdateResult.png";
PsdLoadOptions loadOptions = new PsdLoadOptions();
//Try this
loadOptions.setLoadEffectsResource(true);
PsdImage image1 =(PsdImage) Image.load(sourceFileName,loadOptions);
byte[] layerBytes;
MemoryStream layerMem = new MemoryStream();
OutputStream dstStream = layerMem.toOutputStream();
image1.save(dstStream, new PsdOptions());
layerBytes = layerMem.toArray();
//layerMem = new MemoryStream(layerBytes);
InputStream inputStream = new ByteArrayInputStream(layerBytes);
PsdImage image = new PsdImage(inputStream);
for(int i=0; i < image.getLayers().length; i++ )
{
Layer layer = (Layer) image.getLayers()[i];
System.out.println(i + "DisplayName:" + layer.getDisplayName() + "name:" + layer.getName());
if (i == 11 && image.getLayers()[i] instanceof TextLayer)
{
TextLayer textLayer = (TextLayer)image.getLayers()[i];
IText textData = textLayer.getTextData();
textData.getItems()[0].setText("靠你就是我\r");
textData.getItems()[1].setText("我的\r");
textData.getItems()[2].setText("你的\r");
textData.updateLayerData();
}
}
PngOptions options = new PngOptions();
options.setColorType(PngColorType.TruecolorWithAlpha);
image.save(exportPath,options);
}
多行的问题通过此代码的确OK了,目前就只剩下byte[]->源对象,序列化、反序列化这块了。盼复新的解决答案。
@jsczxielong
请遵循以下线程以获取序列化要求。