1364018504 perlの「imager」で、

標準入力($ENV{'QUERY_STRING'})から入ってきた文字列を、文字化けすることなく、フォント画像にすることはできますか?
どうしても日本語を「~~.cgi?text=あああ」のようにすると文字化けしてしまいます。
perlの文字コードは、Shift_JISです。
パラメータの文字も、Shift_JISです。
Image::magickが使えないので、お願いします。
添付画像は「あああ」です。

回答の条件
  • 1人5回まで
  • 登録:2013/03/23 15:01:44
  • 終了:2013/03/28 15:24:07

ベストアンサー

id:TransFreeBSD No.2

TransFreeBSD回答回数651ベストアンサー獲得回数2622013/03/24 16:09:16

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

id:a-kuma3

string パラメータの文字列は、

  • utf8 フラグ付きで渡すか
  • UTF-8 の文字を utf8 => 1 オプションと一緒に渡してあげる

必要があります。

http://e8y.net/mag/012-imager/

へえ、なるほど。

2013/03/26 09:29:46
id:kamesuta

#!/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/28 15:23:51

その他の回答(1件)

id:a-kuma3 No.1

a-kuma3回答回数4363ベストアンサー獲得回数18002013/03/23 15:37:21

%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 で扱いたいのであれば、文字コードの変換もしてください。

id:kamesuta

ごめんなさい


#!/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;



とやってみたら「あああ」→「ã□□ã□□ã□□」となってしまいました。

2013/03/23 19:23:44
id:a-kuma3

とやってみたら「あああ」→「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

2013/03/24 13:12:24
id:TransFreeBSD No.2

TransFreeBSD回答回数651ベストアンサー獲得回数2622013/03/24 16:09:16ここでベストアンサー

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

id:a-kuma3

string パラメータの文字列は、

  • utf8 フラグ付きで渡すか
  • UTF-8 の文字を utf8 => 1 オプションと一緒に渡してあげる

必要があります。

http://e8y.net/mag/012-imager/

へえ、なるほど。

2013/03/26 09:29:46
id:kamesuta

#!/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/28 15:23:51

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません