前言
psd.js
- 最开始解析psd自然想到使用node,由于psd.js是node和浏览器都可以用,所以就使用psd.js试了下。
- 这里就有个坑,3.3.0版本与3.2.2版本由于config配置修改,导致node上只能获取浏览器版本。所以想在node上解析psd的需要使用3.2.1版本。
- 另外我尝试使用ag-psd这个库解析了下,发现解析出来的格式不太好,并且没有位置信息。
- psd.js在node上解析依然存在坑。由于这个库在解析图片时并不会释放内存。当你需要每个图层都进行解析时,则会导致内存不够,特别是当文件特别大,图层特别多时。
async readpdf() {
const pub = path.resolve(process.cwd(), 'public', 'example.psd');
const psd = PSD.fromFile(pub);
psd.parse();
const tree = await psd.tree().export();
const descendants = await psd.tree().descendants();
const pubb = path.resolve(process.cwd(), 'public');
const tmp = fs.mkdtempSync(path.join(pubb, 'img'));
return new Promise(res => {
const final = v => {
// fs.removeSync(tmp)
res({
layer: v,
document: tree.document,
});
};
const arr = new ArrList(2, final);
for (let i = 0; i < descendants.length; i++) {
const node = descendants[i];
if (node.isGroup()) continue;
if (node.layer && node.layer.image) {
arr.take(async () => {
const res = await this.extractImage(node, tmp, i);
arr.leave(res);
});
}
}
});
}
async extractImage(node, tmp: string, i: number) {
return new Promise(async resolve => {
try {
const name = node.name + i + '.png';
const tmppath = path.resolve(tmp, name);
await node.layer.image.saveAsPng(tmppath).catch(function(err) {
throw 'psd转换错误' + err;
});
const readstream = fs.createReadStream(tmppath);
const uid = uuid.v4();
const res = await this.putFileStream(
readstream,
'tmpimgs' + node.name + uid + '.png',
'yehuozhili',
);
if (res.success) {
resolve({
name: node.name,
width: node.width,
height: node.height,
left: node.left,
right: node.right,
top: node.top,
bottom: node.bottom,
type: 'pic',
imgSrc: res.hash,
});
} else {
resolve(node);
}
} catch (error) {
console.log('psd错误', error);
resolve(node);
}
});
}
- 我在node上尝试使用限定进出等待队列进行解析图片,一样解决不了该问题。
- 这只是一个人传一个大文件内存就爆了,如果很多人传文件,那内存绝对不够,于是就尝试使用浏览器解析。
- 浏览器解析需要使用createObjectURL转换成url地址进行解析,由于把内存使用放到了客户端,这样服务器压力便小多了,还不用怕文件太大。
- 尝试了下在node中因内存解析不出的psd文件在浏览器中可以解析:
const file = fileList[0];
const url = window.URL.createObjectURL(file.originFileObj);
const psd = await PSD.fromURL(url);
const tree = await psd.tree().export();
const descendants = await psd.tree().descendants();
console.log(tree);
const promiseall = [];
for (let i = 0; i < descendants.length; i++) {
const node = descendants[i];
if (node.isGroup()) continue;
if (node.layer && node.layer.image) {
promiseall.push(await extractImage(node));
}
}
const result = await Promise.all(promiseall);
console.log(result);