標準入力($ENV{'QUERY_STRING'})から入ってきた文字列を、文字化けすることなく、フォント画像にすることはできますか?
どうしても日本語を「~~.cgi?text=あああ」のようにすると文字化けしてしまいます。
perlの文字コードは、Shift_JISです。
パラメータの文字も、Shift_JISです。
Image::magickが使えないので、お願いします。
添付画像は「あああ」です。
http://blog.clouder.jp/archives/000721.html
こちら参考にしたと思うのですが、後半、日本語の場合にperlの内部表現へとデコードする必要があると書かれています。また、以下の最後も参考に。
http://e8y.net/mag/012-imager/
用語解説として、flaggedなutf-8=utf8 フラグ付き=perlの内部表現、です。
以下も参考にしてください。
http://perl-users.jp/articles/advent-calendar/2009/casual/10.html
http://hikoboshi.org/perl/utf8.html
%E3%81%82%E3%81%82%E3%81%82
これは化けているんじゃなくて、URL encode されているんですね。
デコードするための CPAN もたくさんあるでしょう。
http://search.cpan.org/~mithun/URI-Encode-0.09/lib/URI/Encode.pm
http://search.cpan.org/~gaas/URI-1.60/URI/Escape.pm
導入できないのであれば、たいしたコードじゃないのでライブラリから抜いてくるか、こんな感じとか。
http://sonic64.com/2003-08-31.html
sub url_decode($) { my $str = shift; $str =~ tr/+/ /; $str =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack('H2', $1)/eg; return $str; }
パラメータの文字も、Shift_JISです。
添付画像は UTF-8 のコードです。
Shift_JIS で扱いたいのであれば、文字コードの変換もしてください。
ごめんなさい
#!/usr/bin/perl
use Jcode;
use URI::Escape;
use Imager;
$buffer = $ENV{QUERY_STRING};
my $string = uri_unescape($buffer);
Jcode::convert(\$string, 'utf8');
my $font = Imager::Font->new(
file => '/home/XXXX/public_html/png/font001.TTF',
color => '#000000',
size => 60,
);
my $bbox = $font->bounding_box(string => $string); # 文字情報を取得
my $img = Imager->new(xsize => $bbox->total_width, ysize => $bbox->font_height);
$img->box(color => '#ffffff', filled => 1); # 背景を白くする
$img->string(
font => $font,
text => $string,
x => 0,
y => $bbox->font_height + $bbox->descent,
aa => 1,
);
print "Content-type: image/png\n\n";
print $img->write(fh => \*STDOUT, type => 'png') or die $img->errstr;
とやってみたら「あああ」→「ã□□ã□□ã□□」となってしまいました。
とやってみたら「あああ」→「a~□□a~□□a~□□」となってしまいました。
正しく文字コード変換ができていません。
Jcode::convert(\$string, 'utf8');
は、
Jcode::convert(\$string, 'sjis', 'utf8');
じゃないでしょうか。
リファレンスを読みましょう。
http://perldoc.jp/docs/modules/Jcode-0.82/Jcode.pod
http://openlab.ring.gr.jp/Jcode/Jcode.html
http://blog.clouder.jp/archives/000721.html
こちら参考にしたと思うのですが、後半、日本語の場合にperlの内部表現へとデコードする必要があると書かれています。また、以下の最後も参考に。
http://e8y.net/mag/012-imager/
用語解説として、flaggedなutf-8=utf8 フラグ付き=perlの内部表現、です。
以下も参考にしてください。
http://perl-users.jp/articles/advent-calendar/2009/casual/10.html
http://hikoboshi.org/perl/utf8.html
string パラメータの文字列は、
- utf8 フラグ付きで渡すか
- UTF-8 の文字を utf8 => 1 オプションと一緒に渡してあげる
必要があります。
http://e8y.net/mag/012-imager/
へえ、なるほど。
#!/usr/bin/perl
use URI::Escape;
use Imager;
use Encode;
use Encode::Guess qw/euc-jp shiftjis 7bit-jis utf8/;
eval {
my $string = decode "Guess", uri_unescape($ENV{QUERY_STRING});
my $font = Imager::Font->new(
file => '/home/XXXX/public_html/font001.TTF',
color => '#000000',
size => 60,
);
my $bbox = $font->bounding_box(string => $string); # 文字情報を取得
my $img = Imager->new(xsize => $bbox->total_width, ysize => $bbox->font_height);
$img->box(color => '#ffffff', filled => 1); # 背景を白くする
$img->string(
string => $string,
utf8 => 1,
font => $font,
x => 0,
y => $bbox->font_height + $bbox->descent,
aa => 1,
);
print "Content-type: image/png\n\n";
print $img->write(fh => \*STDOUT, type => 'png') or die $img->errstr;
};
if ($@) {
print "Content-type: text/html;charset=Shift_JIS\n\n";
print "<html><head><title>error</title></head><body>正しい文字を入れてください</body></html>";
}
ありがとうございます。
Encode.pm を使って内部文字列にするんですね。
できてよかったです。
へえ、なるほど。
2013/03/26 09:29:46#!/usr/bin/perl
2013/03/28 15:23:51use URI::Escape;
use Imager;
use Encode;
use Encode::Guess qw/euc-jp shiftjis 7bit-jis utf8/;
eval {
my $string = decode "Guess", uri_unescape($ENV{QUERY_STRING});
my $font = Imager::Font->new(
file => '/home/XXXX/public_html/font001.TTF',
color => '#000000',
size => 60,
);
my $bbox = $font->bounding_box(string => $string); # 文字情報を取得
my $img = Imager->new(xsize => $bbox->total_width, ysize => $bbox->font_height);
$img->box(color => '#ffffff', filled => 1); # 背景を白くする
$img->string(
string => $string,
utf8 => 1,
font => $font,
x => 0,
y => $bbox->font_height + $bbox->descent,
aa => 1,
);
print "Content-type: image/png\n\n";
print $img->write(fh => \*STDOUT, type => 'png') or die $img->errstr;
};
if ($@) {
print "Content-type: text/html;charset=Shift_JIS\n\n";
print "<html><head><title>error</title></head><body>正しい文字を入れてください</body></html>";
}
ありがとうございます。
Encode.pm を使って内部文字列にするんですね。
できてよかったです。