【javascript】解析psd文件踩坑

前言

  • 最近一直在做解析psd,踩了很多坑,特此总结下。

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);
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 12
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

业火之理

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值