PNG Export functionality

Microsoft Office suite does not allow to import svg images.

I think it would be nice to change the ‘download as SVG image’ functionality in a more generic ‘download as image’, letting the user free to choose between SVG or PNG format.

It’s a great product even without PNG export functionality :wink:


1 Like

Hello @zeta,

we plan to add this feature in the future, but it is not yet determined when it will happen.


Is there a work around to get a good quality image of the diagram?

You can use canvg, i.e. our fork to serialize the SVG underlying our modeling tools to PNG, JPG and so forth. As part of the process you can choose the resolution (i.e. quality / size) of the image, too.

We will not add direct image export functionality in the bpmn-js core in the near future.

I have compiled some codes over the internet and i came up with this solution which has helped me exporting PNG images from SVG source using a Helper class of mine, hope it can suit your needs and help!!

BpmnHelper.savePNG = function () {
    var t = this;
// use the modeler saveSVG method
    this.modeler.saveSVG(function (err, svg) {
        if (err) {
        try {
            // can use the domUrl function from the browser
            var domUrl = window.URL || window.webkitURL || window;
            if (!domUrl) {
                throw new Error("(browser doesnt support this)")

            // figure out the height and width from svg text
            var match = svg.match(/height=\"(\d+)/m);
            var height = match && match[1] ? parseInt(match[1], 10) : 200;
            var match = svg.match(/width=\"(\d+)/m);
            var width = match && match[1] ? parseInt(match[1], 10) : 200;
            var margin = t.margin || 0; // set margin
            var fill = t.fill || '#ffffff'; // set fill color

            // it needs a namespace
            if (!svg.match(/xmlns=\"/mi)) {
                svg = svg.replace('<svg ', '<svg xmlns="" ');

            // create a canvas element to pass through
            var canvas = document.createElement("canvas");
            canvas.width = width + margin * 2;
            canvas.height = height + margin * 2;
            var ctx = canvas.getContext("2d");

            // make a blob from the svg
            var svg = new Blob([svg], {
                type: "image/svg+xml;charset=utf-8"

            // create a dom object for that image
            var url = domUrl.createObjectURL(svg);

            // create a new image to hold it the converted type
            var img = new Image;

            // when the image is loaded we can get it as base64 url
            img.onload = function () {
                // draw it to the canvas
                ctx.drawImage(this, margin, margin);

                // if it needs some styling, we need a new canvas
                if (fill) {
                    var styled = document.createElement("canvas");
                    styled.width = canvas.width;
                    styled.height = canvas.height;
                    var styledCtx = styled.getContext("2d");
                    styledCtx.fillStyle = fill;
                    styledCtx.fillRect(0, 0, canvas.width, canvas.height);
                    styledCtx.strokeRect(0, 0, canvas.width, canvas.height);
                    styledCtx.drawImage(canvas, 0, 0);
                    canvas = styled;
                // we don't need the original any more
                // now we can resolve the promise, passing the base64 url
                var fileName = t.fieldname + '.png';
                var downloadLink = document.createElement('a');
       = fileName;
                downloadLink.innerHTML = 'Get BPMN PNG';
                downloadLink.href = canvas.toDataURL();
                downloadLink.onclick = function (event) {
       = 'hidden';

            // load the image
            img.src = url;

        } catch (err) {
            reject('failed to convert svg to png ' + err);