Convert SVG to image (JPEG, PNG, etc.) in the browser

前端 未结 9 1058
春和景丽
春和景丽 2020-11-21 23:38

I want to convert SVG into bitmap images (like JPEG, PNG, etc.) through JavaScript.

相关标签:
9条回答
  • 2020-11-21 23:52

    The solution to convert SVG to blob URL and blob URL to png image

    const svg=`<svg version="1.1" baseProfile="full" width="300" height="200"
    xmlns="http://www.w3.org/2000/svg">
       <rect width="100%" height="100%" fill="red" />
       <circle cx="150" cy="100" r="80" fill="green" />
       <text x="150" y="125" font-size="60" text-anchor="middle" fill="white">SVG</text></svg>`
    svgToPng(svg,(imgData)=>{
        const pngImage = document.createElement('img');
        document.body.appendChild(pngImage);
        pngImage.src=imgData;
    });
     function svgToPng(svg, callback) {
        const url = getSvgUrl(svg);
        svgUrlToPng(url, (imgData) => {
            callback(imgData);
            URL.revokeObjectURL(url);
        });
    }
    function getSvgUrl(svg) {
        return  URL.createObjectURL(new Blob([svg], { type: 'image/svg+xml' }));
    }
    function svgUrlToPng(svgUrl, callback) {
        const svgImage = document.createElement('img');
        // imgPreview.style.position = 'absolute';
        // imgPreview.style.top = '-9999px';
        document.body.appendChild(svgImage);
        svgImage.onload = function () {
            const canvas = document.createElement('canvas');
            canvas.width = svgImage.clientWidth;
            canvas.height = svgImage.clientHeight;
            const canvasCtx = canvas.getContext('2d');
            canvasCtx.drawImage(svgImage, 0, 0);
            const imgData = canvas.toDataURL('image/png');
            callback(imgData);
            // document.body.removeChild(imgPreview);
        };
        svgImage.src = svgUrl;
     }

    0 讨论(0)
  • 2020-11-21 23:57

    jbeard4 solution worked beautifully.

    I'm using Raphael SketchPad to create an SVG. Link to the files in step 1.

    For a Save button (id of svg is "editor", id of canvas is "canvas"):

    $("#editor_save").click(function() {
    
    // the canvg call that takes the svg xml and converts it to a canvas
    canvg('canvas', $("#editor").html());
    
    // the canvas calls to output a png
    var canvas = document.getElementById("canvas");
    var img = canvas.toDataURL("image/png");
    // do what you want with the base64, write to screen, post to server, etc...
    });
    
    0 讨论(0)
  • 2020-11-21 23:57

    I wrote this ES6 Class which does the Job.

    class SvgToPngConverter {
      constructor() {
        this._init = this._init.bind(this);
        this._cleanUp = this._cleanUp.bind(this);
        this.convertFromInput = this.convertFromInput.bind(this);
      }
    
      _init() {
        this.canvas = document.createElement("canvas");
        this.imgPreview = document.createElement("img");
        this.imgPreview.style = "position: absolute; top: -9999px";
    
        document.body.appendChild(this.imgPreview);
        this.canvasCtx = this.canvas.getContext("2d");
      }
    
      _cleanUp() {
        document.body.removeChild(this.imgPreview);
      }
    
      convertFromInput(input, callback) {
        this._init();
        let _this = this;
        this.imgPreview.onload = function() {
          const img = new Image();
          _this.canvas.width = _this.imgPreview.clientWidth;
          _this.canvas.height = _this.imgPreview.clientHeight;
          img.crossOrigin = "anonymous";
          img.src = _this.imgPreview.src;
          img.onload = function() {
            _this.canvasCtx.drawImage(img, 0, 0);
            let imgData = _this.canvas.toDataURL("image/png");
            if(typeof callback == "function"){
                callback(imgData)
            }
            _this._cleanUp();
          };
        };
    
        this.imgPreview.src = input;
      }
    }
    

    Here is how you use it

    let input = "https://restcountries.eu/data/afg.svg"
    new SvgToPngConverter().convertFromInput(input, function(imgData){
        // You now have your png data in base64 (imgData). 
        // Do what ever you wish with it here.
    });
    

    If you want a vanilla JavaScript version, you could head over to Babel website and transpile the code there.

    0 讨论(0)
  • 2020-11-22 00:03

    I recently discovered a couple of image tracing libraries for JavaScript that indeed are able to build an acceptable approximation to the bitmap, both size and quality. I'm developing this JavaScript library and CLI :

    https://www.npmjs.com/package/svg-png-converter

    Which provides unified API for all of them, supporting browser and node, non depending on DOM, and a Command line tool.

    For converting logos/cartoon/like images it does excellent job. For photos / realism some tweaking is needed since the output size can grow a lot.

    It has a playground although right now I'm working on a better one, easier to use, since more features has been added:

    https://cancerberosgx.github.io/demos/svg-png-converter/playground/#

    0 讨论(0)
  • 2020-11-22 00:06

    Svg to png can be converted depending on conditions:

    1. If svg is in format SVG (string) paths:
    • create canvas
    • create new Path2D() and set svg as parameter
    • draw path on canvas
    • create image and use canvas.toDataURL() as src.

    example:

    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');
    let svgText = 'M10 10 h 80 v 80 h -80 Z';
    let p = new Path2D('M10 10 h 80 v 80 h -80 Z');
    ctx.stroke(p);
    let url = canvas.toDataURL();
    const img = new Image();
    img.src = url;
    

    Note that Path2D not supported in ie and partially supported in edge. Polyfill solves that: https://github.com/nilzona/path2d-polyfill

    1. Create svg blob and draw on canvas using .drawImage():
    • make canvas element
    • make a svgBlob object from the svg xml
    • make a url object from domUrl.createObjectURL(svgBlob);
    • create an Image object and assign url to image src
    • draw image into canvas
    • get png data string from canvas: canvas.toDataURL();

    Nice description: https://web.archive.org/web/20200125162931/http://ramblings.mcpher.com:80/Home/excelquirks/gassnips/svgtopng

    Note that in ie you will get exception on stage of canvas.toDataURL(); It is because IE has too high security restriction and treats canvas as readonly after drawing image there. All other browsers restrict only if image is cross origin.

    1. Use canvg JavaScript library. It is separate library but has useful functions.

    Like:

    ctx.drawSvg(rawSvg);
    var dataURL = canvas.toDataURL();
    
    0 讨论(0)
  • 2020-11-22 00:07

    Here is how you can do it through JavaScript:

    1. Use the canvg JavaScript library to render the SVG image using Canvas: https://github.com/gabelerner/canvg
    2. Capture a data URI encoded as a JPG (or PNG) from the Canvas, according to these instructions: Capture HTML Canvas as gif/jpg/png/pdf?
    0 讨论(0)
提交回复
热议问题