使用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 -- 基础篇(文字&图片)

相关推荐
佛系打工仔1 天前
绘制K线第二章:背景网格绘制
android·前端·架构
明天好,会的1 天前
分形生成实验(五):人机协同破局--30万token揭示Actix-web状态管理的微妙边界
运维·服务器·前端
C_心欲无痕1 天前
nginx - alias 和 root 的区别详解
运维·前端·nginx
我是苏苏1 天前
Web开发:C#通过ProcessStartInfo动态调用执行Python脚本
java·服务器·前端
无羡仙1 天前
Vue插槽
前端·vue.js
哈__1 天前
React Native 鸿蒙跨平台开发:PixelRatio 像素适配
javascript·react native·react.js
用户6387994773051 天前
每组件(Per-Component)与集中式(Centralized)i18n
前端·javascript
SsunmdayKT1 天前
React + Ts eslint配置
前端
开始学java1 天前
useEffect 空依赖 + 定时器 = 闭包陷阱?count 永远停在 1 的坑我踩透了
前端