web-dev-qa-db-ja.com

PHP単一の透明ピクセル(PNGまたはGIF)をレンダリングするスクリプト

1つの透明なドット(PNGまたはGIF)の画像ストリームを返すPHPを作成する必要があります

使いやすいソリューションを教えていただけますか?

55
user333306

透明な1x1 PNG:

header('Content-Type: image/png');
echo base64_decode('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEUAAACnej3aAAAAAXRSTlMAQObYZgAAAApJREFUCNdjYAAAAAIAAeIhvDMAAAAASUVORK5CYII=');

透明な1x1 GIF:

header('Content-Type: image/gif');
echo base64_decode('R0lGODlhAQABAJAAAP8AAAAAACH5BAUQAAAALAAAAAABAAEAAAICBAEAOw==');
163
Sjoerd

PHP 5.4以降では hex2bin を使用できます。これは、base64_decode(以下の空白GIFファイルでテスト済み)よりも約2倍高速です。出力するコード画像は次のようになります。

透明な1x1 PNG:

header('Content-Type: image/png');
die(hex2bin('89504e470d0a1a0a0000000d494844520000000100000001010300000025db56ca00000003504c5445000000a77a3dda0000000174524e530040e6d8660000000a4944415408d76360000000020001e221bc330000000049454e44ae426082'));

透明な1x1 GIF:

header('Content-Type: image/gif');
die(hex2bin('47494638396101000100900000ff000000000021f90405100000002c00000000010001000002020401003b'));

Base64でエンコードされたデータを16進数に簡単に変換できます。

echo bin2hex(base64_decode($data));

またはファイル:

echo bin2hex(base64_decode(file_get_contents($filename)));

しかし、私のベンチマークによると、@ Lukas Liesisが提案するネイティブのPHPエスケープメソッドを使用すると、base64_decodeよりも約12.5倍速くなります。事実上、どのバージョンのPHPでも動作します。コードスニペットは次のとおりです。

透明な1x1 PNG:

header('Content-Type: image/png');
die("\x89\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\x00\x00\x01\x00\x00\x00\x01\x01\x03\x00\x00\x00\x25\xdb\x56\xca\x00\x00\x00\x03\x50\x4c\x54\x45\x00\x00\x00\xa7\x7a\x3d\xda\x00\x00\x00\x01\x74\x52\x4e\x53\x00\x40\xe6\xd8\x66\x00\x00\x00\x0a\x49\x44\x41\x54\x08\xd7\x63\x60\x00\x00\x00\x02\x00\x01\xe2\x21\xbc\x33\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82");

透明な1x1 GIF:

header('Content-Type: image/gif');
die("\x47\x49\x46\x38\x39\x61\x01\x00\x01\x00\x90\x00\x00\xff\x00\x00\x00\x00\x00\x21\xf9\x04\x05\x10\x00\x00\x00\x2c\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x02\x04\x01\x00\x3b");

正規表現を使用すると、このような文字列を簡単に作成できます(一度実行されるため、高速に動作する必要はありません)。

echo preg_replace('/../','\\x\0',bin2hex($data));

またはファイルから:

echo preg_replace('/../','\\x\0',bin2hex(file_get_contents($filename)));
17
Michael Bunkin

人々の質問に対するいくつかの答え:

画像の内容をエコーする必要があります。ヘッダーは、テキストではなく画像を返すことを示しています。したがって、ヘッダーを返した場合、それは単なるヘッダーであり、データはありません。次に、画像のデータを印刷して完了し、画像を送信するだけです:)

ファイルの読み取りは良くありませんが、動作する可能性がありますが、Sjoerdの主な回答に示されているような生データを返す方が良いでしょう。 1つの読み取り操作を保存したからです。ディスクからの読み取りは遅いタスクです。今日では、SSDディスクを使用すると速度が向上しますが、それでも変わりません。ディスクへのI/Oはありません。

Base64デコードなしでもこのコードがありましたが、この画像は白色です:

header('Content-Type: image/gif');
// 1x1px white gif
die("\x47\x49\x46\x38\x37\x61\x1\x0\x1\x0\x80\x0\x0\xfc\x6a\x6c\x0\x0\x0\x2a\x0\x0\x0\x0\x1\x0\x1\x0\x0\x2\x2\x44\x1\x0\x3b");

たぶん、誰かがそのようなデータ文字列にファイルを変換する方法を知っていますか?

6
Lukas