Psd文本图层,文字替换,可否支持超过2以上的换行符\r?

场景: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
请遵循以下线程以获取序列化要求。