Преобразовать двоичные данные в изображение, используя php
У меня есть двоичные данные изображения, сохраненные в моей старой базе данных, они сохранены моим старым разработчиком, теперь я хочу отобразить изображение с помощью PHP, но я не могу.
я пытался imagecreatefromstring
но возвращается FALSE
,
Двоичный пример данных: http://freezinfo.com/gg.php
2 ответа
Учитывая строку, отображаемую в виде текста (за исключением этой последовательности), это цепочка шестнадцатеричных чисел.
В Jpeg магические числа такого файла FF D8
как первые два байта и FF D9
как последние два байта (сравните с Как определить содержимое байта [] является jpeg?).
Эти шестнадцатеричные (шестнадцатеричные) числа могут быть найдены в начале и конце вашей последовательности:
FF00D800FF00 ... 1F00FF00D9000
## ## ## ##
Поиск этих магических чисел также показывает, что шестнадцатеричные значения добавляются с 00
всегда. Это также показывает, что в самом конце дополнительный сингл 0
найден.
Таким образом, четыре символа всегда образуют одно значение. Шестнадцатеричное кодирование это выглядит как 16-битные значения, однако значение никогда не выходит за пределы 8-битного диапазона (0-255), поэтому всегда есть 00
видимый.
С одной только этой информацией тогда можно попытаться превратить это в двоичную строку, которую PHP imagecreatefromstring
может иметь дело с:
$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: плохой код Хаффмана
и следующее изображение:
Это выглядит отчаянно сломленным. Таким образом, вы, вероятно, столкнулись с дополнительной проблемой кодирования здесь. Последний NUL
Байт предполагает, что было сделано больше, и также должна быть причина, по которой данные были сохранены в виде 16-битных шестнадцатеричных значений, а не просто двоичных данных (BLOB-объектов), поскольку базы данных поддерживают это.
Но не тратьте слишком много времени из-за недостатка в программном обеспечении и конфигурации, которые использовались в прошлом, это может быть просто потеря данных, поэтому все, что вы можете сделать, это восстановить из резервных копий.
Данные, которые вы пытаетесь получить, имеют 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
ИЛИ ЖЕ 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)
Заключение
Вам действительно нужно проверить, как вы конвертируете свое изображение в шестнадцатеричное, здесь оно выглядит испорченным.