简体   繁体   English

PHP - “FPDF 错误:不是 PNG 文件”,但图像是

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

I'm currently running into a very odd issue with fpdf.我目前在 fpdf 方面遇到了一个非常奇怪的问题。 I found a similar question with no answer: not a PNG file in FPDF .我发现了一个没有答案的类似问题: 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.我通过浏览器将图像上传到我的文件服务器,然后拉入 fpdf 报告。 When this image is a png, I get the error: "FPDF error: Not a PNG file".当此图像是 png 时,我收到错误消息:“FPDF 错误:不是 PNG 文件”。 I don't get any errors when the uploaded image is a jpg.当上传的图片是 jpg 时,我没有收到任何错误。 This issue seemingly appeared overnight a few weeks ago.这个问题似乎是在几周前一夜之间出现的。

Even stranger, it's only happening with new png's being uploaded.更奇怪的是,这只会在上传新的 png 时发生。 There was a png in a report that was generating fine.报告中有一个 png 生成良好。 When I downloaded that png from the system and re-uploaded it, the errors appeared again.当我从系统下载该 png 并重新上传时,错误再次出现。

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).我已经确定图像实际上是一个 png(通过它的属性)。
  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.我已经检查过他们是否对 PNG 格式或 FPDF 更新有任何更改,但没有运气。
  4. I've converted a jpg that works into a png through gimp.我已经通过 gimp 将可以工作的 jpg 转换为 png。
  5. Converting a png to a jpg through gimp and then uploading the jpg to the system does not generate any errors.通过 gimp 将 png 转换为 jpg,然后将 jpg 上传到系统不会产生任何错误。

WORKAROUND- I've gone ahead and converted png's to jpg's on save, rather than re-encoding the image.变通方法 - 我已经在保存时将 png 转换为 jpg,而不是重新编码图像。 Thanks for the help.谢谢您的帮助。

通过将图片格式手动更改为JPG,然后重复此过程来解决此问题。

The error message indicates that there is something wrong with the first eight bytes of the file (the "png signature"). 错误消息指示文件的前八个字节有问题(“ png签名”)。

Use "od -c | head -1" to inspect the first 16 bytes. 使用“ od -c | head -1”检查前16个字节。 Every PNG file begins with these: 每个PNG文件都以以下内容开头:

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: 如果愿意,请使用“ xxd file.png | head -1”,并希望看到以下内容:

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. 这16个字节是PNG签名以及第一个块的长度和名称。 The first 8 bytes are the format name, plus newlines (linefeeds) and carriage returns that are designed to detect various transmission errors. 前8个字节是格式名称,外加换行符(换行符)和回车符,用于检测各种传输错误。 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". 接下来的8个字节是IHDR块的开头,其长度必须为13,以4字节整数表示,名称为“ IHDR”。

See the PNG specification for details. 有关详细信息,请参见PNG规范

Check the depth of the image. 检查图像的深度。 FPDF supports 24bit depth (i'm not sure about 32bit depth), neither does it support alpha channel. FPDF支持24位深度(我不确定大约32位深度),也不支持alpha通道。 I'd try to reencode to png with ImageMagick (or paint.net under windows). 我会尝试使用ImageMagick(或Windows下的paint.net)将其重新编码为png。

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

I found a crud solution that works for me but this will take little more space on your host.我找到了一个对我有用的 crud 解决方案,但这将在您的主机上占用更多空间。 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.首先获取文件内容并将它们转换为 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.创建您希望文件采用“png”、“jpg”、“jpeg”格式的文件格式数组,并通过文件扩展名对 base64 图像进行解码。 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在设置图像的 FPDF 中,我们遍历重新创建的图像,看看哪个有效,然后停在那里

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();

        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM