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

前有科技后进阶 2024-04-04 08:38:34

大家好,很高兴又见面了,我是"高级前端‬进阶‬",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发,您的支持是我不断创作的动力。

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);参考资料

https://github.com/webtoon/psd

https://repairit.wondershare.com/photo-repair/top-psd-file-openers.html

https://www.linkedin.com/pulse/what-psd-html-css-conversion-md-abdullah-sohag

0 阅读:12

前有科技后进阶

简介:感谢大家的关注