Skip to content

PSD 文件转 PNG

今天主要调查了下如何读取 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 有些区别。

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

Page Layout Max Width

Adjust the exact value of the page width of VitePress layout to adapt to different reading needs and screens.

Adjust the maximum width of the page layout
A ranged slider for user to choose and customize their desired width of the maximum width of the page layout can go.

Content Layout Max Width

Adjust the exact value of the document content width of VitePress layout to adapt to different reading needs and screens.

Adjust the maximum width of the content layout
A ranged slider for user to choose and customize their desired width of the maximum width of the content layout can go.