前言
本文主要介绍如何用 psd.js
来读取 psd
文件的信息,并且分析其中的数据将其轮廓转化为 svg
文件,先放一张效果图

解析结果:

psd.js
使用
关于 psd.js
网上的使用教程参差不齐,官方的使用说明也会有些问题,所以主要先介绍一下使用,以及拿到我们最关心的路径信息。
使用方法和API可以参见这里。
然后我们在 vue
中直接使用 psd.js
通过本地文件导入的方式
js
PSD.fromURL('./test2.psd').then((psd: any) => {
...
})
报错
js
Error: Invalid file signature detected. Got: <!DO. Expected 8BPS.
主要是为文件头 <!DO.
报错
使用 In react, psd.js reports an error 的最后一个回答可以解决这个问题

try this, use Blob,
先将文件转为 blob
格式,然后在使用 psd.js
进行解析
javascript
document.getElementById('psd_file_upload').addEventListener('change', function (file) {
let url = file.target.files[0]
let fr = new FileReader();
fr.readAsDataURL(url);
fr.onload = function () {
console.log(fr.result)
PSD.fromURL(fr.result).then((psd) => {
console.log(psd);
});
}
})
修改写法后成功拿到 psd
文件内容

但是之后调用 psd.tree()
报错 ReferenceError: Buffer is not defined
这是因为 Buffer
对象是 nodejs
特有的,浏览器中不存在这个对象,在 window
上特殊处理添加这个对象。
这个在官方的issue下也有找到对应的问题 use psd.js error: Buffer is not defined
js
import { Buffer } from 'buffer'
window.Buffer = Buffer
成功拿到图层信息
js
console.log(psd)
console.log(psd.tree().export())

获取路径信息
在拿到图层信息之后,我们可以通过 childrenAtPath
方法来获取指定的某一个图层的信息,但是这里要注意的是,这个方法默认只会读取当前第一层级的图层,并不会向下递归,也就是图层如果是在组里面,那就会获取不到。
所以我们可以自己定义一个函数,用于递归获取图层信息:
js
const node = findLayerByName(psd.tree(), targetLayerName)
// 递归查找指定名称的图层,包括嵌套在组内的图层
const findLayerByName = (node: any, name: string): any => {
// 检查当前节点是否匹配
if (node.name === name) {
return node
}
// 如果有子节点,递归查找
if (node._children && node._children.length > 0) {
for (const child of node._children) {
const found = findLayerByName(child, name)
if (found) {
return found
}
}
}
return null
}
这样就能够获取到指定的图层名称的图层信息了。
然后通过图层上自带的 get
方法,就可以获取到当前图层指定的数据,支持的类型可以参考这里
其中 vectorMask
就是我们需要的路径数据,通过 const vectorMask = node.get('vectorMask')
获取。
这里需要注意的是,vectorMask
并不是所有图层都会有的,目前我发现的是只有形状类型的图层才会有路径数据

至于一般的图层要怎么获取这个路径,咱们可以在 ps
中先将想要的图层转为形状,然后在导入,这样就可以获取路径了。
如何将普通图层转为形状,可以参考这篇文章 photoshop如何将普通图层转换为形状图层作为图框 - 技术日志 - 手册与笔记 - 易网
路径数据转化
拿到路径数据后,我们就可以开始把路径转为 svg
文件的 path
形式保存。
通过下面代码我们就能够获取到路径的详细信息,然后关于这些数据的具体含义,在 使用psd.js将PSD转成SVG -- 基础篇(图形) - 掘金 这篇文章里面有着很详细的说明
js
const data = vectorMask.export()
const { paths = [] } = data
const convertedPath: ConvertedPath[] = []
paths.forEach((path: any) => {
...
})

然后依旧是参考 使用psd.js将PSD转成SVG -- 基础篇(图形) - 掘金 里面的方法,创建 parsePath
方法用于解析点位的数据,解析之后在通过 toPath
方法转为 svg
格式,到此,我们也就获得了路径信息对应的 svg
文件,在这之后要怎么处理就全看业务需求了。
项目源码
GitHub - Mr-Yel/pod-editor-demo: pod定制器开发过程碰到的问题,分布解决的 demo 集合
有帮助的小伙伴可以帮忙点个 start
,有问题也可以提出 issue
或者直接在本文评论
参考文章
主要的参考文章,但是原文的源码介绍并不是非常的清晰,所以这篇文章是结合自己的需求以及补充了部分代码实现