You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@pdfbox.apache.org by Markus Barbey <Ba...@gmx.de> on 2016/09/07 14:00:57 UTC

PDFRender does not use cached image versions in renderPageToGraphics(int, Graphics2D)

Hello there,
 
I'm using PDFBox version 2.0.2 and I'm just struggling with the
 
     PDFRenderer#renderPageToGraphics (int, Graphics2D)
 
implementation, which triggers the
 
    PageDrawer#drawImage (PDImage) throws IOException
 
for image drawing. The PDImage instance is holding an image soft reference, once the image has been resolved.
 
When calling
 
     PDFRenderer#renderPageToGraphics (int, Graphics2D)
 
multiple times for the same renderer instance, the
 
    PageDrawer#drawImage (PDImage) throws IOException
 
gets always called with a freshly generated PDImage instance (which has not yet a cached image to use). Therefore the image gets extracted from the PDF stream anew, although it has already been cached in the previously used PDImage instance.
 
 
As a workaround I created my own PDFRender implementation, that uses a dedicated and reused PageDrawer for a visible PDF page. Then I created my own implementation for PageDrawer, that is holding PDImage references, that can be reused. Instead of drawing the freshly generated PDImage, I lookup the first generated one.
 
private class CacheablePageDrawer
        extends PageDrawer {
        public CacheablePageDrawer (PageDrawerParameters pParameters)
            throws IOException {
            super (pParameters);
        }
 
        /** the image cache */
        Map <COSStream, PDImage> fPDImageCache = new HashMap <COSStream, PDImage> ();
 
        @Override
        public void drawImage (PDImage pPdImage) throws IOException
        {
            PDImage vPDImageToDraw = pPdImage;
            if (pPdImage instanceof PDImageXObject) {
                PDImageXObject vPDImageXObject = (PDImageXObject) pPdImage;
                COSStream vCOSStream = vPDImageXObject.getCOSObject ();
                if (!fPDImageCache.containsKey (vCOSStream)) {
                    fPDImageCache.put (vCOSStream,
                                       pPdImage);
                }
                vPDImageToDraw = fPDImageCache.get (vCOSStream);
            }
 
            super.drawImage (vPDImageToDraw);
        }
    }
 
Although it works, it does not seem to be meant to be use that way. So I'm wondering, if there is a better solution to get the image caching to work on multiple renderPageToGraphics(...) calls?
 
 
Thanks,
Markus
 
 

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@pdfbox.apache.org
For additional commands, e-mail: users-help@pdfbox.apache.org


Re: PDFRender does not use cached image versions in renderPageToGraphics(int, Graphics2D)

Posted by Tilman Hausherr <TH...@t-online.de>.
Am 07.09.2016 um 16:00 schrieb Markus Barbey:
> Hello there,
>   
> I'm using PDFBox version 2.0.2 and I'm just struggling with the
>   
>       PDFRenderer#renderPageToGraphics (int, Graphics2D)
>   
> implementation, which triggers the
>   
>      PageDrawer#drawImage (PDImage) throws IOException
>   
> for image drawing. The PDImage instance is holding an image soft reference, once the image has been resolved.
>   
> When calling
>   
>       PDFRenderer#renderPageToGraphics (int, Graphics2D)
>   
> multiple times for the same renderer instance, the
>   
>      PageDrawer#drawImage (PDImage) throws IOException
>   
> gets always called with a freshly generated PDImage instance (which has not yet a cached image to use). Therefore the image gets extracted from the PDF stream anew, although it has already been cached in the previously used PDImage instance.

The PDImageXObject should be cached thanks to the document wide cache 
referenced in PDResources.

I haven't tested your observation yet; the only explanation for now 
would be that your PDF was just created, i.e. not read from a file or a 
stream. (Thus no COSObject references)

Tilman



>   
>   
> As a workaround I created my own PDFRender implementation, that uses a dedicated and reused PageDrawer for a visible PDF page. Then I created my own implementation for PageDrawer, that is holding PDImage references, that can be reused. Instead of drawing the freshly generated PDImage, I lookup the first generated one.
>   
> private class CacheablePageDrawer
>          extends PageDrawer {
>          public CacheablePageDrawer (PageDrawerParameters pParameters)
>              throws IOException {
>              super (pParameters);
>          }
>   
>          /** the image cache */
>          Map <COSStream, PDImage> fPDImageCache = new HashMap <COSStream, PDImage> ();
>   
>          @Override
>          public void drawImage (PDImage pPdImage) throws IOException
>          {
>              PDImage vPDImageToDraw = pPdImage;
>              if (pPdImage instanceof PDImageXObject) {
>                  PDImageXObject vPDImageXObject = (PDImageXObject) pPdImage;
>                  COSStream vCOSStream = vPDImageXObject.getCOSObject ();
>                  if (!fPDImageCache.containsKey (vCOSStream)) {
>                      fPDImageCache.put (vCOSStream,
>                                         pPdImage);
>                  }
>                  vPDImageToDraw = fPDImageCache.get (vCOSStream);
>              }
>   
>              super.drawImage (vPDImageToDraw);
>          }
>      }
>   
> Although it works, it does not seem to be meant to be use that way. So I'm wondering, if there is a better solution to get the image caching to work on multiple renderPageToGraphics(...) calls?
>   
>   
> Thanks,
> Markus
>   
>   
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@pdfbox.apache.org
> For additional commands, e-mail: users-help@pdfbox.apache.org
>


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@pdfbox.apache.org
For additional commands, e-mail: users-help@pdfbox.apache.org