ZF-3392: Png with transparency makes pdf generation performance collapse


here is my test code :

     public function printtestAction()
        require_once 'Zend/Pdf.php';
        $pdf = new Zend_Pdf() ;
        $pdf->pages[] = ($page1 = $pdf->newPage('A4')) ;
        $style = new Zend_Pdf_Style() ;
        $style->setFillColor(new Zend_Pdf_Color_Html('black'));
        $page1->drawText('Test',50,50,'UTF-8') ;
        $background = Zend_Pdf_Image::imageWithPath('pdf_ressources/fond.png');
        $page1->drawImage($background, 0, 0, 597, 841);
        $response = $this->getResponse(); 
        $response->setHeader('Cache-Control', 'public', true) 
            ->setHeader('Content-Description', 'File Transfer', true) 
            ->setHeader('Content-Type', 'application/pdf', true) 
            ->setHeader('Content-Disposition', 'attachment;filename=test.pdf', true) 
            ->setHeader('Content-Transfer-Encoding', 'binary', true) 
        $this->_helper->viewRenderer->setNoRender(true) ;

The image is 597x841. With transparency, it takes about 20 sec, without it's immediate. The image is about 120kB with transparency and about 70kB without.


Alexander, related to your comment on my blog, I can't attach the image since it's a copyrighted one but I think any A4 image with a lot of transparency may cause the problem. I'll test during the week with an other (home made) image to check.

This is unfortunatly a technical limitation to the way the PNG parser works. I assume this is a RGB + Alpha channel image.

The way PDF works is to create two images from one and overlay them as two data streams. PNG is an integrated format. As a result putting out a transparent alpha png requires looping the entire thing and copying out the transparency data.

The key bit of code is...

//Iterate every pixel and copy out rgb data and alpha channel (this will be slow) for($pixel = 0, $pixelcount = ($width * $height); $pixel < $pixelcount; $pixel++) { $imageDataTmp .= $pngDataRawDecoded[($pixel4)+0] . $pngDataRawDecoded[($pixel4)+1] . $pngDataRawDecoded[($pixel4)+2]; $smaskData .= $pngDataRawDecoded[($pixel4)+3]; }

However, this peice of code is being upgraded to the new fileparsers so, any improvement to this should occur after the fileparser upgrades are done. (Which is being worked on in the community, but not at zend afaik)

Alexander - are you actively working on this? If not, I have a newer parser half-finished that should help address this; please assign to me.

Hi Willie!

No. I don't touch these things now. The only thing I would like to add before ZF 1.6 is transparency handling.

Unassigning Zend_Pdf issues currently assigned to me pending decision on ZF 2.0 release timeframe and potential contribution of comprehensive changeset.

I would add that PNG 32 with alpha channel transparencies play a role in this performance degradation. It seems as PNG 24 is not causing as much grief.