美文网首页Node.js程序员
Node.js 两种方法在本地实现 SVG to Image

Node.js 两种方法在本地实现 SVG to Image

作者: 陈陌Chemo | 来源:发表于2019-04-15 16:36 被阅读7次

    canvg2.0

    原址

    https://github.com/canvg/canvg

    获取

    npm install canvg@2.0.0-beta.1 canvas@^2 jsdom@^13 xmldom@^0

    使用
    const fs = require('fs');
    const canvg = require('canvg');
    const { createCanvas } = require('canvas'); // 使用 npm i canvas 来获取
    
    const inputName = 'test.svg';
    const outputName = inputName.replace('.svg','.png');
    try{
        (async() => {
            fs.readFile(inputName ,'utf-8', function(err, data) {
                if (err) {
                    // 读取文件失败
                    throw err;
                }
                const canvas = createCanvas();
                canvg(canvas, data.toString(), {
                    ignoreMouse: true,
                    ignoreAnimation: true,
                    renderCallback: function () {
                        var base64Data = canvas.toDataURL('image/png').replace(/^data:image\/\w+;base64,/, "");
                        var dataBuffer = new Buffer.from(base64Data, 'base64');
                        fs.writeFile(outputName, dataBuffer, function(err) {
                            if (err) {
                                throw err;
                            }
                            console.log(`output file name : ${outputName}`);
                        });
                    }
                });
            });
        })();
    }
    catch{
        console.log('args error');
    }
    
    注意
    • 函数 build() 中的函数 svg.loadXmlDoc() 中的代码 if (svg.ImagesLoaded()) 处,图像未下载完成便尝试渲染,会使转换的 canvas 缺少一些 image 元素,使用间隔计时器解决
    // if (svg.ImagesLoaded()) {
    //  waitingForImages = false;
    //  draw();
    // }
    var drawInvlID = setInterval(function () {
        if (svg.ImagesLoaded()) {
            waitingForImages = false;
            draw();
            clearTimeout(drawInvlID);
        }
    }, 1);
    
    • 函数 build() 中的函数 svg.ToNumberArray() 中的代码 var a = (s || '').match(/-?(\d+(\.\d+)?|\.\d+)(?=\D|$)/gm) || []; 会在遇到科学记数法时出错,使用 canvg1.5 的代码替换可正常工作
    // var a = (s || '').match(/-?(\d+(\.\d+)?|\.\d+)(?=\D|$)/gm) || [];
    var a = svg.trim(svg.compressSpaces((s || '').replace(/,/g, ' '))).split(' ');
    
    • 本人测试时,canvg 中使用过大的 <pattern> 元素会使其中的 <image> “失踪”(长宽比为 1 的情况下以 16384 * 16384 为界),如有解决方法还望指教

    使用 convert-svg-to-png

    原址

    https://github.com/neocotic/convert-svg/tree/master/packages/convert-svg-to-png

    获取

    npm install --global convert-svg-to-png

    使用
    const convertFile = require('convert-svg-to-png');
    const args = process.argv.slice(2);
    try{
      (async() => {
        const outputFilePath = await convertFile(args[0],{"width":args[1],"height":args[2]});    
        console.log(`outputFilePath:${outputFilePath}`);
      })();
    }
    catch{
      console.log('args error');
    }
    
    注意
    • 本人测试中在某些情况下会出现中文乱码的问题,经查验并非编码问题——在删掉一些元素后可以正常显示中文,复原后依旧乱码,如有解决方法还望指教

    相关文章

      网友评论

        本文标题:Node.js 两种方法在本地实现 SVG to Image

        本文链接:https://www.haomeiwen.com/subject/vqauwqtx.html