【问题标题】:PHP - "FPDF error: Not a PNG file", but the image isPHP - “FPDF 错误:不是 PNG 文件”,但图像是
【发布时间】:2015-12-31 02:05:11
【问题描述】:

我目前在使用 fpdf 时遇到了一个非常奇怪的问题。我发现了一个没有答案的类似问题:not a PNG file in FPDF。我通过浏览器将图像上传到我的文件服务器,然后将其拉入 fpdf 报告。当此图像是 png 时,我收到错误:“FPDF 错误:不是 PNG 文件”。当上传的图像是 jpg 时,我没有收到任何错误。这个问题似乎在几周前一夜之间就出现了。

即使是陌生人,也只有在上传新的 png 时才会发生这种情况。报告中有一个生成良好的 png。当我从系统下载该png并重新上传时,错误再次出现。

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

  1. 我已确定图像实际上是 png(通过其属性)。
  2. 我保存图像的方式没有任何改变,但代码如下:

    $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. 我检查了它们是否对 PNG 格式或 FPDF 更新有任何更改,但没有运气。
  4. 我已通过 gimp 将可以工作的 jpg 转换为 png。
  5. 通过 gimp 将 png 转换为 jpg,然后将 jpg 上传到系统不会产生任何错误。

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

【问题讨论】:

  • 用记事本或notepad++打开图片,如果前几个字符不包含'PNG'则不是png文件
  • @ThisNameBetterBeAvailable 幸运的是(或不幸的是?),PNG 确实出现在前几个字符中。
  • 嗯,这是 png 文件的标准,所以你现在知道它不是 png
  • @ThisNameBetterBeAvailable PNG 确实出现在前几个字符中。
  • “pngcheck -v file.png”是什么意思?如果您没有 pngcheck,“identify -verbose file.png”会说什么?错误信息表明文件的前 8 个字节有问题。

标签: php png fpdf


【解决方案1】:

通过手动将图片格式更改为JPG然后重复该过程来修复它。

【讨论】:

  • 我也通过将其保存为 jpg 来修复它,根本无法读取 png。
【解决方案2】:

错误消息表明文件的前八个字节(“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 chunk 的长度,必须是 length=13,用 4 字节整数表示,name="IHDR"。

详情请参阅PNG specification

【讨论】:

  • 在十六进制哑巴之后,我得到:89 50 4e 47-0d 0a 1a 0a-00 00 00 0d-49 48 44 52 .PNG.... ....IHDR,这似乎与您发布的标题相同。还有什么想法吗?
  • 这意味着您十六进制转储的文件确实是PNG。稍后出现问题,可能是在上传过程中。你能具体告诉我们你是如何上传的吗?例如,如果您使用错误的 ftp 传输模式,“ftp”传输可能会混淆 CR (0d) 和 LF (0a) 字节。
【解决方案3】:

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

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

【讨论】:

    【解决方案4】:

    我找到了一个适合我的简单解决方案,但这将占用您主机的更多空间。但是您可以确定哪个扩展有效,然后删除其余的,但这是值得的。

    首先获取文件内容并将它们转换为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();
    
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2016-02-24
      • 2020-11-05
      • 2014-03-30
      • 2012-05-13
      • 2011-03-11
      • 2014-11-15
      • 2016-08-15
      • 2016-03-17
      • 2012-04-20
      相关资源
      最近更新 更多