使用psd.js将psd路径转成svg格式

前言

本文主要介绍如何用 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 或者直接在本文评论

参考文章

主要的参考文章,但是原文的源码介绍并不是非常的清晰,所以这篇文章是结合自己的需求以及补充了部分代码实现

使用psd.js将PSD转成SVG -- 基础篇(图形)

使用psd.js将PSD转成SVG -- 基础篇(文字&图片)

相关推荐
Jerry Lau21 分钟前
go go go 出发咯 - go web开发入门系列(二) Gin 框架实战指南
前端·golang·gin
我命由我123451 小时前
前端开发问题:SyntaxError: “undefined“ is not valid JSON
开发语言·前端·javascript·vue.js·json·ecmascript·js
0wioiw01 小时前
Flutter基础(前端教程③-跳转)
前端·flutter
Jokerator1 小时前
深入解析JavaScript获取元素宽度的多种方式
javascript·css
落笔画忧愁e1 小时前
扣子Coze纯前端部署多Agents
前端
海天胜景1 小时前
vue3 当前页面方法暴露
前端·javascript·vue.js
GISer_Jing1 小时前
前端面试常考题目详解
前端·javascript
Boilermaker19922 小时前
【Java EE】SpringIoC
前端·数据库·spring
中微子2 小时前
JavaScript 防抖与节流:从原理到实践的完整指南
前端·javascript
天天向上10242 小时前
Vue 配置打包后可编辑的变量
前端·javascript·vue.js