How to maintain image quality with FPDF and PHP?

chejnik picture chejnik · Apr 6, 2012 · Viewed 21.8k times · Source

I'm using FPDF with PHP to add an image to a PDF. But the image quality in the PDF is much worse than the original image, as you can see here:

Print screen from web page Print screen from PDF

Relevant code:

$image_height = 40;
$image_width = 40;
$pdf = new FPDF();
$pdf->AddPage();
$start_x = $pdf->GetX();
$start_y = $pdf->GetY();
$pdf->Image('./images/ds_pexeso_ros_0_17.jpg', $pdf->GetX(), $pdf->GetY(), $image_height, $image_width); 
$pdf->Output("pexeso".date("Y-m-d"),"I");

The original image is 150x150 pixels.

Answer

eheydenr picture eheydenr · Jul 22, 2014

I faced the same problem in projects for customers. Blurry pictures in a generated pdf document even with hires images.

It took me a couple of hours, but this is what worked for me.

I have a taken a look at the code and saw that there was a scale factor being set in the constructor of the pdf document:

//Scale factor
if($unit=='pt')
    $this->k=1;
elseif($unit=='mm')
    $this->k=72/25.4;
elseif($unit=='cm')
    $this->k=72/2.54;
elseif($unit=='in')
    $this->k=72;
else
    $this->Error('Incorrect unit: '.$unit);

The scalefactor is depending on the value given in the constructor of the pdf document:

function FPDF($orientation='P',$unit='mm',$format='A4')

The default is 'mm'. In most of my documents I initiate a pdf document like:

$pdf = new PDF('P');

This means that there will be a scalefactor of 72/25.4 = 2.83 used. When I placed an image before I just used:

$this->Image('path/to/file', 0, 0);

This way I got the blurry images. It is also possible to give the width of the image in the command

$this->Image('path/to/file', 0, 0, 200); // for a image width 200

This gave me an image that was far too large. But - and here comes the trick - when you divide the real width by the scalefactor (in my case 2.83) and put this in this statement it gives a perfectly sharp image:

$this->Image('path/to/file', 0, 0, 71); // for a image width 200 / 2.83 = app 71

I hope this works for you too!