古いデータベースに保存されたバイナリ画像データがあり、古い開発者によって保存されています。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
FFD8
は有効な jpeg プレフィックスではありません。ORで始まる必要がありますFfD9
それが JPEG ファイルであり、有効ではないことをどうやって知りましたか?
echo pack("H*", substr($data, 0, 60));
出力
����JFIF
JPEG File Interchange Formatである JFIF への参照が明確に含まれています。
どうすれば修正できますか?
簡単な画像検証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)
結論
画像を hex に変換する方法を実際に調べる必要があります。ここではめちゃくちゃに見えます
テキストとして表示される文字列 (正確にはこのシーケンス) を考えると、それは 16 進数のラインナップです。
Jpeg では、このようなファイルのマジック ナンバーはFF D8
最初の 2 バイトとFF D9
最後の 2 バイトです (バイト [] の内容を識別する方法は jpeg ですか? と比較してください)。
これらの 16 進数 (略して 16 進数) の数字は、シーケンスの最初と最後にもあります。
FF00D800FF00 ... 1F00FF00D9000
## ## ## ##
これらのマジック ナンバーを探すと、16 進数値が00
常に追加されていることもわかります。また、最後に余分なシングル0
が見つかっていることも示しています。
したがって、常に 4 文字で 1 つの値が形成されます。16 進数でエンコードされたこれは 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 データ: 不正なハフマン コード
および次の画像:
これは必死に壊れているように見えます。したがって、おそらくここで追加のエンコードの問題に直面しているでしょう。最後のNUL
バイトは、さらに多くの処理が行われたことを示しており、データベースがサポートしているため、データが単なるバイナリ データ (blob) ではなく 16 ビットの 16 進値として格納されていることにも理由があるはずです。
しかし、あまりにも多くの時間を無駄にしないでください。過去に使用されたソフトウェアと構成に欠陥があるため、これは単にデータが失われる可能性があるため、できることはバックアップから復元することだけです.