PHP - "FPDF error: Not a PNG file",但是图片确实是PNG格式的。

5

我目前遇到了一个关于fpdf的非常奇怪的问题。我在stackoverflow上找到了一个相似的问题,但没有答案:not a PNG file in FPDF。我将一张图片通过浏览器上传到我的文件服务器,然后将其引入fpdf报表中。当这张图片是png格式时,我会收到错误信息:"FPDF error: Not a PNG file"。而当上传的图片是jpg格式时,就不会出现任何错误。这个问题似乎是几周前突然出现的。

更奇怪的是,这只会出现在新上传的png图片上。有一张png图片在报表中生成得很好。当我从系统中下载这张png并重新上传时,错误就再次出现了。

以下是我尝试解决这个问题时采取的一些步骤:

  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.

解决方式- 我已经在保存时将PNG转换为JPG,而不是重新编码图像。感谢您的帮助。


使用记事本或Notepad++打开图像,如果前几个字符不包含“PNG”,则它不是一个PNG文件。 - x13
@这个名字最好可用 幸运的是(或不幸的是?),PNG确实出现在前几个字符中。 - Jesse Cover
这在 PNG 文件中是很标准的,所以现在你知道它不是 PNG 了。 - x13
@ThisNameBetterBeAvailable PNG 出现在前几个字符中。 - Jesse Cover
"pngcheck -v file.png" 会输出什么?如果没有安装 pngcheck,"identify -verbose file.png" 会输出什么?错误信息表明文件的前 8 个字节存在问题。 - Glenn Randers-Pehrson
显示剩余2条评论
4个回答

3

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


我通过将其保存为jpg格式来解决了问题,无法读取png格式。 - james-see

1
错误信息表明文件的前八个字节(“png标识符”)存在问题。
使用“od -c | head -1”检查前16个字节。每个PNG文件都以这些开头:
211   P   N   G  \r  \n 032  \n  \0  \0  \0  \r   I   H   D   R

如果您愿意,可以使用“xxd file.png | head -1”并期望看到以下内容:
0000000: 8950 4e47 0d0a 1a0a 0000 000d 4948 4452  .PNG........IHDR

这16个字节是PNG签名和第一个块的长度和名称。前8个字节是格式名称,加上换行符和回车符,旨在检测各种传输错误。接下来的8个字节是IHDR块的开头,必须将其表示为长度=13的4字节整数,并命名为“IHDR”。
有关详细信息,请参见PNG规范

在获取十六进制哑铃之后,我得到了这样的结果:89 50 4e 47-0d 0a 1a 0a-00 00 00 0d-49 48 44 52 .PNG.... ....IHDR,看上去和您发布的头文件相同。还有其他想法吗? - Jesse Cover
这意味着你转储为十六进制的文件确实是PNG格式。然而,后面可能会出现问题,也许是在上传过程中。你能具体告诉我们你是如何上传的吗?例如,“ftp”传输如果使用了错误的传输模式,可能会改变CR(0d)和LF(0a)字节。 - Glenn Randers-Pehrson

0

我找到了一个适合我的crud解决方案,但这会占用您主机上更多的空间。但是您可以确定哪个扩展名有效并删除其余部分。然而这是值得的。

首先将文件内容转换为base64_encode。 创建一个包含您想要文件格式的数组,如“png”,“jpg”,“jpeg”,并通过循环遍历文件扩展名来解码base64图像。这将在您的文件夹中重新创建具有三个文件扩展名的图像。

使用

try{
}catch (Exception $e) {
}

循环遍历并找到可用的图像扩展名并使用它。 这是我的完整代码

$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++;
}

在您的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();

        }
    }
}

0

检查图像的深度。FPDF支持24位深度(我不确定32位深度),也不支持alpha通道。 我建议尝试使用ImageMagick(或在Windows下使用paint.net)重新编码为png。

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接