13

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.

chejnik
  • 219
  • 1
  • 6
  • 24
  • I also have this problem, did you figure it out? Maybe I can ask it a different way... If an image is 100 pixels x 100 pixels, what is the FPDF width and height to use to ensure image scaling does not occur? – Scott Sep 28 '13 at 01:20
  • TCPDF is an alternative - although you probably don't want to hear that! You could try it to compare quality however in case it is not library related. – Luke Barker Mar 19 '14 at 14:07

3 Answers3

13

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!

eheydenr
  • 1,000
  • 11
  • 10
  • This solution only works for scaling down an image. Let's say the raw image is really high definition. Using this solution for 1:1 ratio (rawwidth:pdfwidth) will not do it. – Abel Callejo Dec 05 '18 at 01:17
1

I think the problem could be related to:

 $image_height = 40;
 $image_width = 40;

With these two instructions your are setting the dimensions the image will have in the pdf.

But if the original image is bigger than 40x40 the scaling of the image can cause quality problem.

So what i suggest:

ab_dev86
  • 1,952
  • 16
  • 21
  • Thank you for suggestion. The fact is that I want to maintain the original width and height (150x150 px). What values for $image_height and $image_width I should set to maintain original width and height? – chejnik Apr 06 '12 at 07:40
  • Well if in your pdf you want the image 150x150 then change the first two lines of your file: with $image_height = 150; $image_width = 150; – ab_dev86 Apr 06 '12 at 07:41
  • The units used in fdpf are not clear to me. As it is said in manual, for example for width - Width of the image in the page. There are three cases: If the value is positive, it represents the width in user unit If the value is negative, the absolute value represents the horizontal resolution in dpi If the value is not specified or equal to zero, it is automatically calculated. I am not sure how to set my user unit to pixels or what resolution to use to acheive not scaling images. Tx. – chejnik Apr 06 '12 at 08:05
  • I have set $pdf = new FPDF("P", "mm", "A4"); That way I have define the user unit to mm, and convert px to mm (150px corresponds to 39.6875). Still the image is of worse quality. – chejnik Apr 06 '12 at 08:19
  • If simply $image_height = 150; $image_width = 150; $pdf = new FPDF(); ... ? – ab_dev86 Apr 06 '12 at 08:49
  • That way fpdf enlarge the picture to 150mmx150mm (with bad quality too) – chejnik Apr 06 '12 at 09:03
  • Well I'am not sure that "150px corresponds to 39.6875" always works, maybe can depend on screen resolution or other properties... I would try to resize the with GD as described in my post until it fits the pdf and doesn't loose quality. – ab_dev86 Apr 06 '12 at 09:15
  • I guess image quality depends on your pdf DPI setting. For instance you couldn't have a good image quality inside a 72dip pdf because creating it the image will be reduced to 72dpi even it was 300dpi. – Luca Marletta Feb 15 '14 at 03:35
0

FPDF with a statement like this to set the user unit to mm $pdf=new FPDF('P','mm','Letter');

<?php 

    require_once('fpdf.php');
    $image_height = 40;
    $image_width = 40;
    $pdf = new FPDF('P','mm','Letter');
    $pdf->AddPage();
    $start_x = $pdf->GetX();
    $start_y = $pdf->GetY();
    $pdf->Image('./images/ds_pexeso_ros_0_17.jpg',$start_x+0,$start_y-2,40);
   $pdf->Output("pexeso".date("Y-m-d"),"I");
?>

FPDF made a very good looking result.