我有二进制图像数据保存在我的旧数据库中,它是由我的旧开发人员保存的,现在我想使用 PHP 显示图像,但我不能。
我试过imagecreatefromstring
了,但它返回了FALSE
。
二进制示例数据: http: //freezinfo.com/gg.php
我有二进制图像数据保存在我的旧数据库中,它是由我的旧开发人员保存的,现在我想使用 PHP 显示图像,但我不能。
我试过imagecreatefromstring
了,但它返回了FALSE
。
二进制示例数据: http: //freezinfo.com/gg.php
您尝试检索的数据具有 HTML 及其 HEX 格式,但图像已损坏或无效。
要获取数据:
// $url = "log.txt";
$url = "http://freezinfo.com/gg.php";
// Load Data from URL
$data = file_get_contents($url);
// Remove ALL HTML Tags
$data = strip_tags($data);
错误
现在让我们检查标题
echo substr($data, 0, 4); // returns FF00
FF00
不是有效的 jpeg 前缀 它应该以FFD8
OR开头FfD9
我怎么知道它是 JPEG 文件并且它无效?
echo pack("H*", substr($data, 0, 60));
输出
����JFIF
它显然参考了 JFIF,即JPEG 文件交换格式
如何解决?
快速图像验证imagecreatefromstring
$data = pack("H*", $data); // Convert from hex
$im = @imagecreatefromstring($data);
var_dump($im); // returns false
再次查看图像标题$data
..我可以看到一个模式
FF00D800FF00E000000010004A00460049
^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^
我注意到它00
已被插入,因此删除它实际上会给我们一个有效的图像标题FFD8
你可以用一个简单的循环来解决这个问题
// Trim all Spaces
$data = trim($data);
$newData = "";
for($i = 0; $i < strlen($data); $i += 4) {
$newData .= $data{$i} . $data{$i + 1};
}
$newData = pack("H*", $newData);
$im = imagecreatefromstring($newData);
var_dump($im); // resource(6, gd)
输出
resource(6, gd)
结论
您确实需要检查将图像转换为十六进制的方式,这里看起来很混乱
给定显示为文本的字符串(确切地说是这个序列),它是一组十六进制数字。
在 Jpeg 中,这种文件的幻数是FF D8
前两个字节和FF D9
最后两个字节(与How to identify contents of a byte[] is a jpeg?相比)。
这些十六进制(简称十六进制)数字也可以在序列的开头和结尾找到:
FF00D800FF00 ... 1F00FF00D9000
## ## ## ##
寻找这些神奇的数字还揭示了十六进制值00
总是附加的。它还表明,在最后0
发现了一个额外的单曲。
所以四个字符总是形成一个值。十六进制编码这看起来像 16 位值,但该值永远不会超过 8 位范围 (0-255),因此始终00
可见。
仅凭这些信息,就可以尝试将其转换为 PHPimagecreatefromstring
可以处理的二进制字符串:
$string = implode('', // map array of binary strings to binary string
array_map('chr', // map ord integer value to character
unpack('v*', // unsigned short (always 16 bit, little endian byte order)
pack("H*", $data) // hex to binary (high nibble first)
)));
然后使用这样的字符串
$result = imagecreatefromstring($string);
imagejpeg($result, 'test.jpg');
显示以下 PHP 错误通知:
imagecreatefromstring(): gd-jpeg, libjpeg: 可恢复的错误: 损坏的 JPEG 数据: 错误的 Huffman 代码
和下图:
这看起来非常破碎。所以你可能在这里面临一个额外的编码问题。最后一个NUL
字节表明已经完成了更多工作,并且必须有原因将数据存储为 16 位十六进制值而不仅仅是二进制数据 (blob),因为数据库对此有支持。
但是不要浪费太多时间,因为过去使用的软件和配置存在缺陷,这可能只是数据丢失,所以你所能做的就是从备份中恢复。