bpampuch / pdfmake

Client/server side PDF printing in pure JavaScript
http://pdfmake.org
Other
11.65k stars 2.04k forks source link

Images in header/footer #1278

Open FinnStutzenstein opened 6 years ago

FinnStutzenstein commented 6 years ago

Hi,

we have encounterd a performance problem with images included in header and/or footer. Example: A PDF with 112 pages. Without images in the header: 580kb. With an image (filesize ~50kb) in the header the filesize increases to 25mb! Also the generation time as well as the used memory increases such, that some users cannot export the PDF because the browser gets out of memory.

In fact single images are not the problem, but I think that for each page, the image is rendered into the header and 112 identical images (so 5,5mb; where the other 20mb come from I don't know) are included.

Is there a possibility, that one can supply an image which is put in the some kind of meta-section and just references to this image are given? The effect would be, that the image is included once and the pdf viewer has to render this image to the given places in contrast to putting the image to every single place.

Thanks!

liborm85 commented 6 years ago

Hi. I tried 3 scenarios (see below). If image is directly defined using base64 in header/footer (test 3) it causes a problem and images are inserted multiple times into pdf. Before I fix it, please use way specified in test 1 (images in vfs_fonts.js file) or test 2 (images defined in docDefinition in images section).


Test 1 (image is in vfs_fonts.js file): WORKS OK

var dd = {
    header: function(currentPage, pageCount, pageSize) {
        return [
            { image: 'sampleImage.jpg', height: 30, width: 100 }
        ]
    },
    content: [
        {text: 'pageText', pageBreak: 'after'},
        {text: 'pageText', pageBreak: 'after'},
        {text: 'pageText', pageBreak: 'after'},
        {text: 'pageText', pageBreak: 'after'},
        {text: 'pageText', pageBreak: 'after'},
        {text: 'pageText', pageBreak: 'after'},
        {text: 'pageText', pageBreak: 'after'},
        {text: 'pageText', pageBreak: 'after'},
        {text: 'pageText', pageBreak: 'after'}
    ]
}

Test 2 (image in base64 is defined in docDefinition in section images): WORKS OK

var dd = {
    header: function(currentPage, pageCount, pageSize) {
        return [
            { image: 'building', height: 30, width: 100 }
        ]
    },
    content: [
        {text: 'pageText', pageBreak: 'after'},
        {text: 'pageText', pageBreak: 'after'},
        {text: 'pageText', pageBreak: 'after'},
        {text: 'pageText', pageBreak: 'after'},
        {text: 'pageText', pageBreak: 'after'},
        {text: 'pageText', pageBreak: 'after'},
        {text: 'pageText', pageBreak: 'after'},
        {text: 'pageText', pageBreak: 'after'},
        {text: 'pageText', pageBreak: 'after'}
    ],
    images: {
        building: 'data:image/jpeg;base64,/9j/4RC....NsI5p3f//Z'
    }
}

Test 3 (image is as base64): NOT WORK CORRECTLY

var dd = {
    header: function(currentPage, pageCount, pageSize) {
        return [
            { image: 'data:image/jpeg;base64,/9j/4RC5RXhpZgAATU.....ONsI5p3f//Z', height: 30, width: 100 }
        ]
    },
    content: [
        {text: 'pageText', pageBreak: 'after'},
        {text: 'pageText', pageBreak: 'after'},
        {text: 'pageText', pageBreak: 'after'},
        {text: 'pageText', pageBreak: 'after'},
        {text: 'pageText', pageBreak: 'after'},
        {text: 'pageText', pageBreak: 'after'},
        {text: 'pageText', pageBreak: 'after'},
        {text: 'pageText', pageBreak: 'after'},
        {text: 'pageText', pageBreak: 'after'}
    ]

}
FinnStutzenstein commented 6 years ago

Thanks for the fast reply! Yes, we define the image directly with the base64 data. I've implemented custom fonts for the pdf (https://github.com/OpenSlides/OpenSlides/pull/3568; especially note the changes in core/pdf-worker.js and core/pdf.js if you are interested) where we are overwriting PdfMake.vfs on the client with our custom font data. When this font-feature is merged (currently under review) I'll try your first example by adding the image data not the the docDefinition but to the vfs object.

The different possibilities to include images should be documented in the readme ;)

jonasao commented 6 years ago

From the ReadMe:

{
      // if you reuse the same image in multiple nodes,
      // you should put it to to images dictionary and reference it by name
      image: 'mySuperImage'
}

Have you tried this? - Given that the page header/footer can be seen as "multiple nodes".

riyazpanarwala commented 6 years ago

I want to insert multiple images. So Where we found the documentation related to 'images dictionary' ?

mraxus commented 5 years ago

Thanks to the suggestion of @liborm85 I got a reduction in a 8 page file size of 6.4MB down to 1.6MB for option 2. Fantastic. Thanks for the guidance <3