比 PSD.js 更强的下一代 PSD 解析器,支持 WebAssembly

比 PSD.js 更强的下一代 PSD 解析器,支持 WebAssembly

1.什么是 @webtoon/ps

@webtoon/ps 是 Typescript 中轻量级 Adobe Photoshop .psd/.psb 文件解析器,对 Web 浏览器和 NodeJS 环境提供支持,且做到零依赖。

Fast zero-dependency PSD parser for the web and Node.js

@webtoon/ps 使用标准 ES2015+ 功能,因为零依赖性使其比其他 PSD 解析器(ag-psd:200 KiB,PSD.js:443 KiB)更小,压缩后只有大约 100 KiB,同时使用 WebAssembly 来加速图像数据的解码。

目前 Chrome>=57、Firefox>=52、Safari>=11、Edge>=79、Node>=12 版本都已经支持。@webtoon/ps 在 Github 通过 MIT 协议开源,有超过 1.1k 的 star,是一个值得关注的前端开源项目。

2.如何使用 @webtoon/ps

浏览器环境使用

@webtoon/psd 作为纯 ECMAScript 模块提供,但是必须与 Webpack 或 Rollup 等捆绑器捆绑。 @webtoon/psd 将 PSD 文件读取为 ArrayBuffer,开发者可以使用 FileReader 或 File 加载 PSD 文件:

import Psd from "@webtoon/psd";
const inputEl: HTMLInputElement = document.querySelector("input[type='file']");
inputEl.addEventListener("change", async () => {
  const file = inputEl.files[0];
  const result = await file.arrayBuffer();
  const psdFile = Psd.parse(result);
    // 获取包含 PSD 或 PSB 文件的 ArrayBuffer
    // 并返回一个新的 Psd 对象
  const canvasElement = document.createElement("canvas");
  const context = canvasElement.getContext("2d");
  const compositeBuffer = await psdFile.composite();
  const imageData = new ImageData(
    compositeBuffer,
    psdFile.width,
    psdFile.height
  );
  canvasElement.width = psdFile.width;
  canvasElement.height = psdFile.height;

  context.putImageData(imageData, 0, 0);
  document.body.append(canvasElement);
});

为了提高性能,非常建议在 Web Worker 而不是主线程中解析 PSD 文件。

NodeJS 环境使用

@webtoon/psd 不支持 Node.js 缓冲区,开发者必须显式提供底层 ArrayBuffer。

import * as fs from "fs";
import Psd from "@webtoon/psd";

const psdData = fs.readFileSync("./my-file.psd");
// 在 Buffer 中传递 ArrayBuffer 实例
const psdFile = Psd.parse(psdData.buffer);

由于 @webtoon/psd 是作为 ES 模块提供的,因此开发者必须使用动态 import() 或捆绑器在 CommonJS 代码中运行:

const Psd = await import("@webtoon/psd");

3.图层遍历

Psd 对象是包含图层和组(即图层组)对象的树,其提供了一个 Children 属性,是顶级图层和组的数组。

每个 Group 对象都提供一个 Children 属性,是直接属于当前图层组的图层和组的数组。Psd、Group 和 Layer 对象提供了一个类型字段,可用于区分每种类型:

import Psd, {Node} from "@webtoon/psd";
// 递归遍历图层和组
function traverseNode(node: Node) {
  if (node.type === "Layer") {
    // 图层
  } else if (node.type === "Group") {
    // 组
  } else if (node.type === "Psd") {
    // PSD 类型
  } else {
    throw new Error("Invalid node type");
  }

  node.children?.forEach((child) => traverseNode(child));
}
traverseNode(psdFile);

Psd 对象还提供了 layers 属性,是图像中所有 Layer(包括嵌套的)的数组。

for (const layer of psdFile.layers) {
  doSomething(layer);
}

4.解码图像数据

开发者可以使用 Psd.prototype.composite() 和 Layer.prototype.composite() 解码整个图像或单个图层的像素信息。

请注意,要使 Psd.prototype.composite() 正常工作,PSD/PSB 文件需要以 “最大化兼容性” 模式保存。 否则,将不返回任何数据。

// 解码整个图像
pixelData = await psd.composite();

// 提取图层的像素数据,并应用所有图层和图层组效果
// (currently, only the opacity is supported)
layerPixelData = await layer.composite();
// 提取图层的像素数据,仅应用图层自身的效果
layerPixelData = await layer.composite(true, false);
// 提取图层的像素数据,无任何效果
layerPixelData = await layer.composite(false);
  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值