当我尝试对手机中的某些 jpg 文件使用 imagecreatefromjpeg() 到我的网站时,我遇到一些问题,无法验证它们是实际的 jpg 图像。
我尝试时遇到的错误:
PHP Warning: imagecreatefromjpeg(): gd-jpeg: JPEG library reports unrecoverable error: Not a JPEG file: starts with 0x00 0x00
PHP Warning: imagecreatefromjpeg(): "/tmp/phpBGoiQg" is not a valid JPEG file
到目前为止,我自己能弄清楚的是,一些错误的照片的最大区别是这些照片是在你编辑后来自 Instagram 的,这个问题与以下任一方面有关:元数据、编码或压缩。如果我在手机上编辑它们并再次保存图像,它会上传得很好,但这就是问题所在。
我找不到解决此问题的真正解决方案,因此我的用户不必担心编辑照片以上传它们。如果有人能给我指出正确的方向,我很乐意自己找出答案。
目前,我设置了一项检查,仅通知用户特定照片已被跳过。但我真的希望能够以某种方式修复它们?
if (exif_imagetype($file_temp_name) === IMAGETYPE_JPEG) {
//do resize, else skip and report issue.
}
更新
因此,在处理完此问题并弄清楚 jpg 似乎确实是 jpg2000 图像(由于十六进制为 00 00 00 开始)后,我一直在尝试弄清楚如何通过 php 上传来处理它。
我尝试了一些 imagick 的东西,比如 exec() 函数来尝试转换图像,并且还尝试重新保存为不同的格式。没有运气。
我不知道从这里该去哪里,因为我找不到任何类似的情况。也许我不擅长谷歌搜索,但我真的很感激任何指点。
代码片段:
case 'image/jpeg': //case 'image/pjpeg':
if (exif_imagetype($file_temp_name) === IMAGETYPE_JPEG) {
$image_res = imagecreatefromjpeg($file_temp_name);
} else {
// Check for the JPEG 2000 magic number (00 00 00)
$fileContents = file_get_contents($file_temp_name);
if (substr($fileContents, 0, 3) === "\x00\x00\x00") {
$uploadedFile = $file_temp_name;
$outputFilename = "NEW-$file_name";
if (file_exists($uploadedFile)) {
$command = "convert $uploadedFile $outputFilename";
exec($command);
if (file_exists($outputFilename)) {
$_report .= "Image conversion successful! ";
$image_res = imagecreatefromjpeg($outputFilename);
} else {
$_report .= "Image conversion failed. [$uploadedFile to $outputFilename] ";
exec($command, $output, $returnCode);
$_report .= "Error: " . implode("\n", $output); // Log the error messages
}
} else {
$_report .= "Image doesn't exist. [$uploadedFile to $outputFilename] ";
}
}
}
break;
签名以 FF D8 FF
开头。您可以验证是否使用十六进制编辑器打开 JPEG 文件。如果您的文件确实以
00 00
开头(值得检查),那么它要么已损坏,要么根本不是 JPEG 图片。它可能是一个JPEG 2000 文件,尽管名称如此,但实际上是不同的格式:
00 00 00 0C 6A 50 20 20 0D 0A 87 0A
值得注意的是,一些代理会自动以不同格式(例如 webp)重新编码原始文件以节省带宽但保留原始名称,因此您最终会得到一个名为 foo.jpg
的文件,它实际上根本不是 JPEG。