0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Webサーバ上で生成した画像データをWebクライアントに出力する

Last updated at Posted at 2024-10-20

概要

Webサーバ上で画像を動的に生成し、Webブラウザ等のクライアントに表示させたりダウンロードさせたりしたいことがあります。
本稿ではその手順についてPerl, PHPでのサンプルコードを紹介します。

前提

画像データの生成方法について

本稿では、簡略化のため、画像データについてはファイルから読み込んでそのまま出力することとします。
GDライブラリを使用した画像データの生成方法については別途説明したいと思います。

サンプルコード

基本的な流れ

  1. 画像データを生成する
    ここでは、スクリプトと同じディレクトリのsample.pngという名前の画像ファイルを読み込むようにします。
  2. HTTPヘッダを出力する
    Content-TypeヘッダでPNG形式を指定し、Content-Dispositionヘッダで出力するファイル名を指定します。(後者は必須ではありません。)
    Perl版ではロジックの関係上画像ファイルの長さを取得できるので、Content-Lengthヘッダをサボらずに出力しています。
  3. 画像データを出力する

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版をローカルで動かしてみます。

  1. コマンドラインより以下を実行
    php -S localhost:8080 php_img_stream.php
  2. Webブラウザで以下のURLにアクセス
    http://localhost:8080/
  3. 以下のように画像が表示されれば成功

サンプルコードのありか

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"');
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?