• このエントリーをはてなブックマークに追加

はじめに

GD::Barcode::QRcode を使うと,任意のテキストデータを QR コードな画像を簡単に生成できます.

本エントリでは,それを簡単な Plack アプリケーションにしてみたものをご紹介.

生成したものをそのまま表示するのではなく,拡大率やパディングの指定なんかを行えるようにもしてます.

パラメータ

t: 変換するテキストデータ
r: 拡大率
p: パディング
e: ECCの値(よくわかってない)

実行サンプル

http://localhost:5000/?r=10&t=http://iss.ms/
ss-1361541011
http://localhost:5000/?r=3.5&p=10&t=%68%74%74%70%73%3A%2F%2F%6D%61%70%73%2E%67%6F%6F%67%6C%65%2E%63%6F%2E%6A%70%2F%6D%61%70%73%3F%66%3D%71%26%73%6F%75%72%63%65%3D%65%6D%62%65%64%26%68%6C%3D%65%6E%26%67%65%6F%63%6F%64%65%3D%26%71%3D%68%74%74%70%3A%25%32%46%25%32%46%69%73%73%2E%6D%73%25%32%46%67%70%73%6C%6F%67%25%32%46%32%30%31%33%25%32%46%43%79%63%6C%65%6D%65%74%65%72%2D%43%79%63%6C%65%2D%32%30%31%33%30%32%31%37%2D%30%38%33%33%2E%6B%6D%6C%26%61%71%3D%26%73%6C%6C%3D%33%34%2E%39%33%37%35%34%38%2C%31%33%37%2E%32%36%32%30%37%34%26%73%73%70%6E%3D%30%2E%30%31%32%30%31%34%2C%30%2E%30%32%32%35%33%31%26%67%3D%68%6F%67%65%26%62%72%63%75%72%72%65%6E%74%3D%33%2C%30%78%36%30%30%33%36%38%31%32%38%31%63%31%63%34%31%39%3A%30%78%61%33%63%35%30%30%62%61%61%30%61%37%62%35%32%33%2C%30%26%69%65%3D%55%54%46%38%26%74%3D%6D%26%6C%6C%3D%33%35%2E%32%33%39%30%33%2C%31%33%37%2E%30%37%32%36%33%39%26%73%70%6E%3D%30%2E%30%36%37%32%39%38%2C%30%2E%31%32%33%34%32%35%26%7A%3D%31%33/
ss-1361541095

コード

次のコードを psgi ファイルとして plackup すれば,とりあえず動作します:

use 5.10.0;
use warnings;
use utf8;
use Plack::Request;
use Encode;
use GD::Barcode::QRcode;
use Try::Tiny;
 
my $app = sub {
    my $env = shift;
    my $req = Plack::Request->new($env);
 
    my $t = $req->param('t') // '';
    my $e = $req->param('e') // 'M';
    my $p = $req->param('p') // 0;
    my $r = $req->param('r') || 1;
 
    my $qr;
    my $msg;
    for my $v ( 1 .. 40 ) {
        try {
            $qr = GD::Barcode::QRcode->new(
                encode_utf8($t),
                { Ecc => $e, Version => $v },
            );
        } catch {
            $msg = shift;
        };
        last if $qr;
    }
 
    # error
    if ( ! $qr ) {
        return [
            500,
            [ 'Content-Type' => 'text/plain' ],
            [ $msg ],
        ];
    }
 
    my $img_qr = $qr->plot();
    my $pr = 4 * $r;  # 4 は 生成時に付加されるパディング [px]
 
    my ($w0, $h0) = $img_qr->getBounds();
    my ($w1, $h1) = ( int($w0 * $r), int($h0 * $r) );
 
    my $img = GD::Image->new(
        $w1 - 2 * ($pr - $p),
        $h1 - 2 * ($pr - $p),
    );
    $img->copyResized(
        $img_qr,
        - ($pr - $p), - ($pr - $p),
        0, 0,
        $w1, $h1,
        $w0, $h0,
    );
 
    return [
        200,
        [ 'Content-Type' => 'image/png' ],
        [ $img->png ],
    ];
};

おわりに

こういった画像生成系アプリケーションって, curl とかで引っぱれるようにしておけば便利ですよね!