Jesse Cover
Jesse Cover

Reputation: 51

PHP - "FPDF error: Not a PNG file", but the image is

I'm currently running into a very odd issue with fpdf. I found a similar question with no answer: not a PNG file in FPDF. I have an image uploaded through a browser to my file server, and then pulled into a fpdf report. When this image is a png, I get the error: "FPDF error: Not a PNG file". I don't get any errors when the uploaded image is a jpg. This issue seemingly appeared overnight a few weeks ago.

Even stranger, it's only happening with new png's being uploaded. There was a png in a report that was generating fine. When I downloaded that png from the system and re-uploaded it, the errors appeared again.

Here are some of the steps I've taken while attempting to troubleshoot the issue:

  1. I've made sure the image is actually a png (through its properties).
  2. Nothing has changed with the way I've been saving the images, but here's the code:

    $original = $time."_".$name."_o.".$extension;
    $thumbnail = $time."_".$name."_t.".$extension;  
    include('SimpleImage.php');
    $image = new SimpleImage();
    $image->load($_FILES['file']['tmp_name']);
    $image->save($A_path."images/".$original);
    $image->resizeToHeight(200);
    $image->save($A_path."images/thumbs/".$thumbnail);
    $photo = "images/".$original;
    $thumb = "images/thumbs/".$thumbnail;
    
  3. I've checked to see if their were any changes to the PNG format or FPDF updates, with no luck.
  4. I've converted a jpg that works into a png through gimp.
  5. Converting a png to a jpg through gimp and then uploading the jpg to the system does not generate any errors.

WORKAROUND- I've gone ahead and converted png's to jpg's on save, rather than re-encoding the image. Thanks for the help.

Upvotes: 5

Views: 19625

Answers (4)

INNOCENT KIBOTO
INNOCENT KIBOTO

Reputation: 1

I found a crud solution that works for me but this will take little more space on your host. But you can determine which extension worked and delete the rest However its worth it.

First take the file contents and convert them to base64_encode. Create an array of the file formats you want the file to be in "png","jpg","jpeg" and decode the base64 image looping through the file extensions. This recreates the image with three file extensions in your folder.

Use the

try{
}catch (Exception $e) {
}

to loop trough and find which image extension works and use it. Here is my full code

$base64 = base64_encode(file_get_contents("full/domain/path/to/image"));
$f_ex = array('.png', '.jpg', '.jpeg');  //array of extensions to recreate 

$path = "path/to/new/images"; //this folder will have there images.

$i = 0;
$end = 3;

while ($i < $end) {

    $data = base64_decode($base64); //decode the image file from base64

    $filename = "unique_but_memorable_filename(eg invoice id)" . $f_ex[$i]; //$f_ex loops through the file extensions

    file_put_contents($path . $filename, $data); //we save our new images to the path above

    $i++;
}

Inside your FPDF where your image is set, we loop through the images we recreated and see which one works and stop there

try {
    $filename = "remember_unique_but_memorable_filename(eg invoice id)" . $f_ex[0];
    $logo = "your domail.com where image was stored" . '/' . $path . $filename;
    $pdf->Image($logo, 10, 17, 100, 100);

    //Put your code here to delete the other image formats.

} catch (Exception $e) {

    try {
        $filename = "remember_unique_but_memorable_filename(eg invoice id)" . $f_ex[1];
    $logo = "your domail.com where image was stored" . '/' . $path . $filename;
    $pdf->Image($logo, 10, 17, 100, 100);
    
    //Put your code here to delete the other image formats.

    } catch (Exception $e) {
        try {
            $filename = "remember_unique_but_memorable_filename(eg invoice id)" . $f_ex[2];
    $logo = "your domail.com where image was stored" . '/' . $path . $filename;
    $pdf->Image($logo, 10, 17, 100, 100);

        //Put your code here to delete the other image formats.

        } catch (Exception $e) {
            //if all the three formats fail, lets see the error
            echo 'Message: ' . $e->getMessage();

        }
    }
}

Upvotes: 0

rojoloco47
rojoloco47

Reputation: 71

Fixed it by changing the picture format manually to JPG and then repeating the process.

Upvotes: 3

Glenn Randers-Pehrson
Glenn Randers-Pehrson

Reputation: 12455

The error message indicates that there is something wrong with the first eight bytes of the file (the "png signature").

Use "od -c | head -1" to inspect the first 16 bytes. Every PNG file begins with these:

211   P   N   G  \r  \n 032  \n  \0  \0  \0  \r   I   H   D   R

If you prefer, use "xxd file.png | head -1" and expect to see this:

0000000: 8950 4e47 0d0a 1a0a 0000 000d 4948 4452  .PNG........IHDR

These 16 bytes are the PNG signature and the length and name of the first chunk. The first 8 bytes are the format name, plus newlines (linefeeds) and carriage returns that are designed to detect various transmission errors. The next 8 bytes are the beginning of the IHDR chunk, which must be length=13 expressed as a 4-byte integer, and the name="IHDR".

See the PNG specification for details.

Upvotes: 1

Orsiris de Jong
Orsiris de Jong

Reputation: 3016

Check the depth of the image. FPDF supports 24bit depth (i'm not sure about 32bit depth), neither does it support alpha channel. I'd try to reencode to png with ImageMagick (or paint.net under windows).

convert input.png -depth 8 +matte output.png

Upvotes: 0

Related Questions