概要
Webサーバ上で画像を動的に生成し、Webブラウザ等のクライアントに表示させたりダウンロードさせたりしたいことがあります。
本稿ではその手順についてPerl, PHPでのサンプルコードを紹介します。
前提
画像データの生成方法について
本稿では、簡略化のため、画像データについてはファイルから読み込んでそのまま出力することとします。
GDライブラリを使用した画像データの生成方法については別途説明したいと思います。
サンプルコード
基本的な流れ
- 画像データを生成する
ここでは、スクリプトと同じディレクトリのsample.pngという名前の画像ファイルを読み込むようにします。 - HTTPヘッダを出力する
Content-TypeヘッダでPNG形式を指定し、Content-Dispositionヘッダで出力するファイル名を指定します。(後者は必須ではありません。)
Perl版ではロジックの関係上画像ファイルの長さを取得できるので、Content-Lengthヘッダをサボらずに出力しています。 - 画像データを出力する
PHP, Perlの順にコードを載せます。
PHP版
php_img_stream.php
<?php
//出力するファイルを読み込む(ここではPNGを前提とする)
$file_name = "./sample.png";
$contents = file_get_contents($file_name);
//画像を出力する前に明示的にレスポンスヘッダを出力する
header("Content-Type: image/png");
header('Content-Disposition: inline; filename="sample.png"');
//PNGイメージでストリーム出力
echo $contents;
?>
Perl版
PHP版のheader()関数のようなものを使用していないので、ヘッダと本文の間の空行を忘れないようにします。
perl_img_stream.pl
#! /usr/bin/perl
use strict;
sub main() {
my $file_name = "sample.png";
open(my $fh, "<", $file_name) or die();
binmode($fh);
my $buf = "";
my $bin = "";
while(sysread($fh, $buf, 256)) {
$bin .= $buf;
}
close($fh);
print "Content-Length: ", length($bin), "\n";
print "Content-Type: image/png", "\n";
print "Content-Disposition: filename=sample.png", "\n";
print "\n";
print $bin;
}
&main();
実行例
PHPのビルトインサーバを利用して、PHP版をローカルで動かしてみます。
- コマンドラインより以下を実行
php -S localhost:8080 php_img_stream.php
- Webブラウザで以下のURLにアクセス
http://localhost:8080/ - 以下のように画像が表示されれば成功
サンプルコードのありか
GitHubにサンプルコードとサンプル画像を置いています。
https://github.com/kk-outlaw/image_stream
追記:直接ダウンロードさせたい場合
ブラウザに直接表示させるのではなくダウンロードのダイアログから保存させたい場合、以下のようにContent-Dispositionヘッダを変更します。
header('Content-Disposition: attachment; filename="sample.png"');
これを応用すると、画像ファイルのみならずZIPファイルなどもダウンロードさせることができます。
header('Content-Type: application/zip');
header('Content-Disposition: attachment; filename="sample.zip"');