Skip to content

PSD 文件转 PNG

🏷️ PSD Aspose

今天主要调查了下如何读取 PSD 文件并转化为 PNG 的方法,最好是支持读取每个图层的信息,并将每个图层转化为 PNG 文件。

在本地简单的测试了一下,使用了 PSD 和 PSB 格式的文件各一个。由于时间有限,测试的样本比较少,而且测试的文件也比较小 (只有几 M )。

Java

通过 Java 程序转换主要是参考这篇博客,其中记载了三种方法。

Aspose.PSD for Java

官方文档:https://docs.aspose.com/psd/java/

  • 可以将整个 PSD 转成 PNG(支持 PSB 和 PSD)
  • 可以获取每个图层的位置、大小,并支持将每个图层导出为单独的 PNG 图片
  • 需要付费(试用时导出的图片左上角会有一个类似水印的方框)

注意: 添加 Java Maven 依赖时要注意下版本,感觉尽量使用新版的应该兼容性会比较好。测试时先用的是文档中的版本( 20.2 ),结果各种出错,改成最新版本( 21.7 )就好了。

Aspose.PSD for Java 的包不在官方 Maven 仓库里,需要添加 <repository> 配置:

xml
<repositories>
    <repository>
        <id>AsposeJavaAPI</id>
        <name>Aspose Java API</name>
        <url>http://repository.aspose.com/repo/</url>
    </repository>
</repositories>

添加依赖:

xml
 <dependencies>
    <dependency>
        <groupId>com.aspose</groupId>
        <artifactId>aspose-psd</artifactId>
        <version>21.7</version>
        <classifier>jdk16</classifier>
   </dependency>
</dependencies>

保存图层为 PNG 文件的示例:

java
// Load a PSD file as an image and caste it into PsdImage
PsdImage psdImage = (PsdImage) Image.load(file.getInputStream());

// Create an instance of PngOptions class
PngOptions pngOptions = new PngOptions();
pngOptions.setColorType(PngColorType.TruecolorWithAlpha);

// Loop through the list of layers
String tmpFileName = RandomUtil.randomString(10);
psdImage.save(String.format("%s.png", tmpFileName), pngOptions);

for (int i = 0; i < psdImage.getLayers().length; i++) {
    // Convert and save the layer to PNG file format.
    psdImage.getLayers()[i].save(String.format("%s_layer_%d.png", tmpFileName, i), pngOptions);
}

TwelveMonkeys + Thumbnailator

TwelveMonkeys: https://mvnrepository.com/artifact/com.twelvemonkeys.imageio/imageio-psd
Thumbnailator: https://mvnrepository.com/artifact/net.coobird/thumbnailator

  • 支持将整个文件转成 PNG
    • 转 PSB 文件成功
    • 转 PSD 文件报错
  • 不支持获取单独的图层

奇怪的是转测试的 PSD 格式文件时会报错,估计还是兼容性有些问题。

添加依赖:

xml
<!-- https://mvnrepository.com/artifact/net.coobird/thumbnailator -->
<dependency>
    <groupId>net.coobird</groupId>
    <artifactId>thumbnailator</artifactId>
    <version>0.4.17</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.twelvemonkeys.imageio/imageio-psd -->
<dependency>
    <groupId>com.twelvemonkeys.imageio</groupId>
    <artifactId>imageio-psd</artifactId>
    <version>3.8.3</version>
</dependency>

示例代码:

java
BufferedImage bufferedImage;
try {
    bufferedImage = ImageIO.read(new File(fileName));
} catch (IOException e) {
    throw new RuntimeException(e);
}

try {
    String thumbnailFileName = String.format("twelve_monkeys_%s_%d.png", fileName, System.currentTimeMillis());
    Thumbnails.of(bufferedImage)
            .size(bufferedImage.getWidth(), bufferedImage.getWidth())
            .toFile(new File(thumbnailFileName));
    log.info("thumbnailFileName: {}", thumbnailFileName);
} catch (IOException e) {
    throw new RuntimeException(e);
}

PsdReader

这篇博客中提供了一个博客作者自己实现的 PSD 读取类(PsdReader),是根据 PSD 的格式规范实现的。

测试结果:

  • 转 PSB 文件没有报错,但是图片仅有黑色背景
  • 转 PSD 文件成功

代码示例(PsdReader 类代码比较长,这里就不贴了,详见原博客):

java
PsdReader psdReader = new PsdReader(new File(fileName));
BufferedImage bufferedImage = psdReader.getImg();
String thumbnailFileName = String.format("psd_reader_%s_%d.png", fileName, System.currentTimeMillis());
try {
    ImageIO.write(bufferedImage,"png",new File(thumbnailFileName));
} catch (IOException e) {
    throw new RuntimeException(e);
}

JavaScript

JavaScript 版貌似都是基于 PSD.js 这个模块的。

PSD.js

项目仓库:https://github.com/meltingice/psd.js

这个模块支持获取各个图层的具体信息,详细介绍和用法见项目仓库(不过貌似文档并不多)。

测试结果:

  • PSB 文件转换失败,只有黑色的背景
    • 应该是没有获取到图层信息导致的
  • PSD 文件转 PNG 成功
    • 可以获取到图层的信息

安装 psd 模块

bash
npm install psd

示例代码:

javascript
var PSD = require('psd');
var psd = PSD.fromFile("1.psb");
psd.parse();

console.log("1.psb", psd.tree().export());
// console.log(psd.tree().childrenAtPath('A/B/C')[0].export());

// You can also use promises syntax for opening and parsing
PSD.open("1.psb").then(function (psd) {
  return psd.image.saveAsPng('./1-output.png');
}).then(function () {
  console.log("Finished!");
});

// You can also use promises syntax for opening and parsing
PSD.open("2.psd").then(function (psd) {
    console.log("2.psd", psd.tree().export());
    return psd.image.saveAsPng('./2-output.png');
  }).then(function () {
    console.log("Finished!");
  });

1.psb 文件的解析结果:

json
{
  children: [],
  document: {
    width: 1747,
    height: 1137,
    resources: {
      layerComps: [],
      resolutionInfo: [Object],
      guides: [Array],
      slices: []
    }
  }
}

2.psd 文件的解析结果:

json
{
  children: [
    {
      type: 'group',
      visible: true,
      opacity: 1,
      blendingMode: 'normal',
      name: 'iPhone 4',
      left: 163,
      right: 838,
      top: 137,
      bottom: 1468,
      height: 1331,
      width: 675,
      children: [Array]
    },
    {
      type: 'group',
      visible: true,
      opacity: 1,
      blendingMode: 'normal',
      name: 'iPhone 4 Side',
      left: 902,
      right: 1009,
      top: 138,
      bottom: 1456,
      height: 1318,
      width: 107,
      children: [Array]
    },
    {
      type: 'layer',
      visible: false,
      opacity: 1,
      blendingMode: 'normal',
      name: 'Background',
      left: 0,
      right: 1234,
      top: 0,
      bottom: 1600,
      height: 1600,
      width: 1234,
      mask: {},
      text: undefined,
      image: {}
    },
    {
      type: 'layer',
      visible: true,
      opacity: 1,
      blendingMode: 'normal',
      name: 'Background',
      left: 0,
      right: 1234,
      top: 0,
      bottom: 1600,
      height: 1600,
      width: 1234,
      mask: {},
      text: undefined,
      image: {}
    }
  ],
  document: {
    width: 1234,
    height: 1600,
    resources: {
      layerComps: [],
      resolutionInfo: [Object],
      guides: [Array],
      slices: []
    }
  }
}

Python

Python 的 PIL 图像处理库支持 PSD 文件的解析。

  • 根据文档,可以导出每个图层的图片
  • 试用了 Psd2Png 里生成好的 exe 文件,导出的图层文件高宽是一样的(背景透明)

参考项目:

  1. https://github.com/delta-kimigatame/Psd2Png
  2. https://github.com/zhexie314/psd2png

总结

综上,付费的 Aspose.PSD for Java 表现最好,文档也比较全。免费的里面 Python 的测试结果最好,导出的 PNG 结果和 Aspose.PSD 有些区别。

因为时间有限,测试的样本也比较少,以上结论仅供参考。