Jspdf: addImage with compression repeats same image

Created on 10 Feb 2017  路  6Comments  路  Source: MrRio/jsPDF

So.. This is pretty weird. I have a function that crops an image in different pieces and adds them to different pages of my pdf document. However, when I enable compression in the addimage function, the first image is repeated.

Code:

html2canvas(srcElWrapper, {
        background:'#fff',
        onrendered: function(canvas) {

            var image = new Image();
            image.src = canvas.toDataURL("image/jpeg");

            orient = 'p';

            // TEST
            l = {
                orientation: orient,
                unit: 'mm',
                format: 'a4',
                compress: true,
                fontSize: 8,
                lineHeight: 1,
                autoSize: false,
                printHeaders: true
            };

            var doc = new jsPDF(l);

            widthOfOnePiece = 992;
            heightOfOnePiece = 1403;

            numColsToCut = Math.ceil(canvas.width/widthOfOnePiece);
            numRowsToCut = Math.ceil(canvas.height/heightOfOnePiece);

            totalWidth = 0;
            totalHeight = 0;
                for(var x = 0; x < numColsToCut; x++) {
                    for(var y = 0; y < numRowsToCut; y++) {
                        var canvas = document.createElement('canvas');
                        canvas.width = widthOfOnePiece;
                        canvas.height = heightOfOnePiece;
                        var context = canvas.getContext('2d');
                        context.drawImage(image, x * widthOfOnePiece, y * heightOfOnePiece, widthOfOnePiece, heightOfOnePiece, 0, 0, canvas.width, canvas.height);

                        // THIS OPENS RIGHT PART OF IMAGE:
                        window.open(canvas.toDataURL());


                        if ( x > 0 ) { doc.addPage(); }

                        // THIS WORKS: doc.addImage(canvas.toDataURL(), 'jpg', 5, 15, 210, 297);

                        // THIS DOESNT:
                        doc.addImage(canvas.toDataURL(), 'jpg', 5, 15, 210, 297,'','FAST');
                    }
                }

            doc.save('testsaves.pdf');
}

Most helpful comment

This has little to do with compression. Have a look. Despite the compression option, what else did change?

doc.addImage(canvas.toDataURL(), 'jpg', 5, 15, 210, 297);
doc.addImage(canvas.toDataURL(), 'jpg', 5, 15, 210, 297,'','FAST');

You found it? Well, that empty string is setting an alias. The idea is that jsPDF reuses images with known aliases. So of course your first image is repeated again and again, you told jsPDF to do so.

There are basically three options:

  1. Set alias to null or undefined.
  2. Put all arguments in an object, omitting alias and pass this to addImage. It's basically the same as option 1, but looks better to some.
  3. Set an unique alias for each unique image. I would always do this: if no alias is set, jsPDF will calculate a hash instead, which can easily double or tripple the time it uses for adding an image.

All 6 comments

In the for-loop, the following line opens the correct part of image each time:

window.open(canvas.toDataURL());

However when adding it to my document, this adds the right image:
doc.addImage(canvas.toDataURL(), 'jpg', 5, 15, 210, 297);

And this just repeats the same image:
doc.addImage(canvas.toDataURL(), 'jpg', 5, 15, 210, 297,'','FAST');

Any suggestions?

This has little to do with compression. Have a look. Despite the compression option, what else did change?

doc.addImage(canvas.toDataURL(), 'jpg', 5, 15, 210, 297);
doc.addImage(canvas.toDataURL(), 'jpg', 5, 15, 210, 297,'','FAST');

You found it? Well, that empty string is setting an alias. The idea is that jsPDF reuses images with known aliases. So of course your first image is repeated again and again, you told jsPDF to do so.

There are basically three options:

  1. Set alias to null or undefined.
  2. Put all arguments in an object, omitting alias and pass this to addImage. It's basically the same as option 1, but looks better to some.
  3. Set an unique alias for each unique image. I would always do this: if no alias is set, jsPDF will calculate a hash instead, which can easily double or tripple the time it uses for adding an image.

@MrRio
Issue should be closed ;)

@sgelb You could also use the following to leverage compression without caching repeated images.

pdf.addImage(base64Image, 'png', x, y, width, height, NaN, 'FAST');

NaN is the key here :)

https://github.com/MrRio/jsPDF/blob/d00a9dfde5fdf4f9f3c5f67a9231391975793c17/docs/modules_addimage.js.html#L339

You know, since NaN === NaN returns false

@sgelb You could also use the following to leverage compression without caching repeated images.

pdf.addImage(base64Image, 'png', x, y, width, height, NaN, 'FAST');

NaN is the key here :)

https://github.com/MrRio/jsPDF/blob/d00a9dfde5fdf4f9f3c5f67a9231391975793c17/docs/modules_addimage.js.html#L339

You know, since NaN === NaN returns false

This isn't working for me, still getting repeated images (first one in iteration) in generated pdf.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

palmoni picture palmoni  路  4Comments

arulmb0136 picture arulmb0136  路  4Comments

sajesh1985 picture sajesh1985  路  5Comments

0721Betty picture 0721Betty  路  4Comments

andmaltes picture andmaltes  路  4Comments