THE PSP攻略+α 〜SONYへの挑戦状〜
記事の内容
前へ |
次へ
perlとImageMagickで日本語が使えないとか言ってる奴ちょっと来い
2009/10/21 02:55
訪問者ログを見たら偉大な方の訪問履歴があった。
悪い意味での訪問でなければ良いのですが…
とりあえず執筆依頼おめでとうございます。
さて、勝手移植コンバーターでよく使われるようになったperlやらImageMagickですが、最近は日本語が上手く使えないというのをよく耳にします。
以前から色々言いたいことがあったので、これを機会に急遽記事を書くことになりました。
主に開発者向けの内容ですが、コンバーター利用者も読んで頂ければ、上手くコンバートできない時の問題解決に繋がるかもしれません。
ちなみに、タイトルは某掲示板風にしただけで、別に怒り狂ってるわけではないです。
内容は少々過激なものになっていますが…。
一気にリアルが忙しくなり長い間すべての更新が滞ってる状態なので、各地でのレスも止まってしまって申し訳ないです。
この記事の完成も何日遅れになるのだろうか…。
2009/10/21 19:31
私の使用しているperlとImageMagickのバージョンを追記。
2009/10/21時点での私が使用しているperlとImageMagickのバージョン。
perl v5.10.0 build 1003 (確認方法: perl -v)
ImageMagick 6.5.3-2 Q16 (確認方法: convert -version)
まず、perlを正しく使えてる人がほとんど居ません。
なんだかいきなり偉そうですが、率直な意見はこうです。
別に組むのがへたくそだとかそういう意味ではなく、使い方を間違えていたり、perlらしいスクリプトじゃないのを良く見かける。
そういう私は、何年か前にCGIとしてperlを使用し、ファイルのアップローダーを組んだぐらいで、大して本格的なものは作ってないのだが…。(今の世代の人は知らないかな…)
個人的には、perlは玄人向けの言語で使うのは簡単だが、使いこなすのは難しい言語だと思っている。
そもそも、perlはUN*X系OS用に開発された言語で、UN*X系のOSには標準装備されている。
Windowsにも移植されているが、色々な面でWindowsユーザーには使い辛い。
perlは実行時にコンパイルする形式なので、利用者もperlを導入する必要がある。
perlはコンソールアプリケーションなのだが、最近はGUIアプリが標準なのでコマンドプロンプトを使う時点で梃子摺る人が多い。
そういう人は、perlのスクリプトファイルを直接実行して起動させているようだ。
インストール時に関連付けされるので、わざわざperlから起動させる必要が無いので便利なのだが、エラーが出たときに色々と困る。
「黒いウィンドウが開いてすぐ閉じるのですが(ry」なんていう酷い質問を見たことがある人も少なくは無いであろう…。
これはperlに限らず、batファイルでバッチコマンドを使用するコンバーターにも見られる質問である。
誰しも最初はWindows初心者なので仕方が無いわけだが、コンバーター作者側がちゃんと工夫をしないとエンドユーザーに優しくないし、不具合時の報告も情報不足でコンバーター作者側も困る。
これに関する簡易的な対処法だが、batファイルでpauseコマンドを使用する。
pauseコマンドを使用すれば、キーを入力するまでコマンドプロンプトが閉じないので、エラーが出た場合の確認に役立つ。
まあ、これはperlに関係が無く、Windowsの問題なのでbatを利用する際にコンバーター作者が配慮するべきことなのだが…
ImageMagickでは、バッチファイルでconvertコマンドを実行して変換している人も居るが、Windowsには標準で別のconvertコマンドがあり、誤作動の危険性があるのでオススメできない。
この場合、ImageMagickのconvertを絶対パスで指定すれば問題なく使える。
絶対パスを調べるときに、ImageMagickがインストールされてるかの確認も行えるので、より安全である。
エンドユーザーだけでなく、開発者側も日本語が使えないなどの不具合に遭遇している。
正確には、「perlの使い方を間違っている。」
果たして、開発者側がperlを理解していないのに、エンドユーザーが不具合に遭遇した場合、対処できるのだろうか。
何が言いたいかというと、他の人が使ってるからと無理をしてperlを使うなら他の言語を使え。
これは最初の「perlらしいスクリプトじゃない」という部分に当てはまることだが、わざわざperlを使う必要性の無いコーディングが多い。
他の言語で組んだ方が明らかに可読性も高く、スマートな記述になる。
正規表現が使いたいだけなら、DLLやらなんやらで他の言語にも容易に組み込んで使える。
要は自分のレベルや性格に合った言語を使うべきで、エンドユーザーにも優しい実行形式(exe形式)で出力する言語が望ましい。
perlの使い方を間違っているとの話だが、皆さんは文字コードについて考えてスクリプトを組んでいるだろうか。
「だめ文字のことでしょ」と思った人は正解で多くの方はこれを理解している。
なのだが、対処方法は間違っていたりする。
今のところ、正確な方法で対処してる人は見たことが無い。
現に、最近ではImageMagickを使用するときに日本語名のファイルが使えないという問題がちらほら出てきている。
ここで少し、だめ文字と対策について簡単に説明してみよう。
まず、だめ文字とは何なのか。
Windowsでは日本語にShiftJISという文字コードが使われているが、これは2バイト目に\(円記号orバックスラッシュ)が使用されている。
\はperl以外の言語でも特殊な文字(エスケープ文字)として使用されているので、上手いこと文字として認識されず、省かれてしまう。
昔のC言語コンパイラーでも同様の問題があったが、今ではShiftJISにも対応しているので問題は無い。
perlはUN*X系OSの言語なので、ShiftJISは考慮されておらず、このだめ文字問題が発生するのである。
簡単な対処法は、エスケープさせないことである。
perlで文字列を扱う場合はダブルクォーテーションマーク(")とシングルクォーテーションマーク(')の2種類使える。
これにはちゃんと意味があって、シングルクォーテーションで括ると文字がエスケープされない。
これは変数の展開なども含まれている。
print "構わない" → 高ない(構に含まれる\が省かれて文字化けする)
print '構わない' → 構わない(そのまま表示できる)
という感じになる。
他にも、\自体を表示したい場合は\\と表記すれば良いので、「構\わない」と書けばダブルクォーテーションで括っても、内部的には\が2個ある状態なので省かれなくて済む。
もしShiftJISに対応している場合でも、\単体は(だめ文字化けの時と同じく)省かれるので、何の問題も無い。
詳しくはwikipediaなどに載っているので、わかり辛い人はそっちを読んで頂きたい。
上記の方法で、表示に関するだめ文字対策はできたが、文字列をマッチングするときにShiftJISだと問題が発生してくる場合がある。
ShiftJISでは2バイト目にさまざまなASCII文字(半角英字や記号など)を含んでるので、ASCII文字でマッチングした場合に検索元の2バイト目に引っかかったり、[]や|などの特殊な文字も含まれているので、おかしな結果になったりエラーが出たりします。
そこで、2バイト目にASCII文字が含まれない文字コードに変換してマッチングするという方法が有効である。
この方法は、だめ文字対策も兼ねることになるので、エスケープについて考える必要もない。
多くの方はEUC-JPという文字コードを使っているのだが、これはUN*Xで日本語を扱うときに使う文字コードでもあり、非常に相性が良い。
この文字コードを使う場合にも、少々注意が必要なのだが…。
ちゃんと対応してる人が居ない気もする。
これもperlの使い方を間違っているという理由の一つだが、後で根本的な問題が出てくるので割愛しておく。
perlの文字コードについて長々と書いたが、要約すればスクリプトをEUCで書き、外部から読み込んだテキストをEUCに変換すれば良い。
という話で済みそうなのだが、これは昔の話で今は違う。
正確にはperl5.8から仕様が変わったので、もう何年も前から変わっているのである。
そして、この文字コードの問題はImageMagickにも深く関係してくる。
つまり、perlやImageMagickが日本語に対応していないのではなく、間違った文字コードを使用しているために使えていないのである。
何日もかけて記事を書くのに私も疲れてきたのでそろそろperlとImageMagickについてのまとめを書いていこうか。
まず、perl5.8以降、ImageMagick6.4.1-6以降は内部の文字コードにUTF-8を使用している。
UTF-8を使えば、perlの内部では日本語が1文字として扱われ、マッチングも正常に行われる。もちろんスクリプトもUTF-8で書ける。
perlではEncodeモジュールが標準で付属されているので、jcodeなどを使用する必要も無い。
こいつはさまざまな文字コードを相互変換できるのでjcodeの代用にもなるだろう。
EUCの時と同じく、ShiftJISで読み込んだシナリオスクリプトを一々UTF-8に変換する必要があるかと思われるだろうが、perlが正式にUTF-8やその他の文字コードに対応しているので、openで読み込む際に文字コードを指定すれば自動でUTF-8に変換してくれる。
プラグマで設定をすれば、一度文字コードを設定するだけで、後は普通にファイルの入出力時に変換してくれる。
ImageMagickで、日本語が扱えないという問題には、実は3種類の環境が存在する。
少し前にたまたま他の方のブログのコメントを元に調べたら判明した。
1つ目は一部使えない文字があるが、ほとんどの日本語が使えるバージョン。
2つ目は「ー」などが使えなくて1つ目より使えない文字が多いが、大体の日本語は使えるバージョン。
3つ目は一切の日本語が使えないバージョン。
それぞれの具体的なバージョンは6.3.3、6.3.7、6.5.3-2である。
「ー」などの文字が使えないとのことだが、これもだめ文字の一種である。
ーを1バイトに分解すると、[0x81/0x5B]となる。
この2バイト目はASCII文字の『 [ 』にあたる。
ここでImageMagickの更新履歴を見てみよう。
6.3.3〜6.3.7の間の更新に、『 [ 』を含む何かの更新があるはずだ。
6.3.6-2の更新を見てみると、PDFの頁を『image.pdf[1-3]』という方法で指定できるようになっている。ビンゴだ。
このため、「ー」が含まれると「[」があると誤認識して上手く処理されないのである。
そこで、ImageMagickで使えない文字を調べて、出力するスクリプトを組んでみた。結果は以下の通り。
2バイト目に『 [ ] { } 』の4文字のどれかが来ると使えない模様。
それぞれ16進数で0x5B,0x5D,0x7B,0x7Dである。
FC2のHTMLエディタが糞使えないのでテキストエリアもjavascriptも使えん…
文字のリストは記事の最後につけてます。
#ジャンプ#
3つ目の理由は…。
先ほど6.4.1-6から文字コードがUTF-8に変わったと書いたのでお分かりであろう。
私のほうでは未確認だが、6.3.3でも使えない日本語があるらしいので、過去のバージョンのものを使うのではなく、最新版を使うべきである。
もちろんPerlMagickも同じなので、perlでUTF-8を使用していれば何の問題もないのである。
ちなみに、これらのことは公式などを調べると、ちゃんと説明が書いてある。
文字コードの対応についても、ちゃんと更新履歴に書いてあった。
この記事の内容はすべて、perlやImageMagickを何年も使っていない私が数日で調べ、解明した結果である。
意味はお察し頂きたい。
perlを使う気があるのならば、最新版を使い、仕様を把握し、正しい文字コードでperlらしいスクリプトを書くべきである。
配布する場合はエンドユーザーのレベルも要求される。
バージョン違いによる不具合を防ぎたいのであれば、perlやImageMagickのバージョンを確認し、対応しているかを確認してからスクリプトを実行させるべきである。
エンドユーザーに優しい仕様にしたいのなら、開発者側がバージョンのチェックをすると良いかもしれない。
また、コマンドプロンプトがすぐに閉じないように工夫すべきである。(readmeにコマンドプロンプトの使い方を書くだけでも効果的である)
上手くスクリプトが動かない場合、その場しのぎの方法でやり過ごすのではなく、原因を究明して言語を正しく使おうとしているだろうか。
perlにImageMagickなどのモジュールを導入する際、ppmコマンドを使うことを知っている人は何人居るのだろうか。
ppmコマンドはユーザー名が日本語の場合には正常に動かないことを何人知っているのだろうか。
自分はperlが使いこなせてるつもりでも、この記事の内容を全部正しく実行していただろうか。
私自身もほとんどperlを使っていないので、まだまだ知らなかったり間違っていることがあるだろう。
プログラミングの上達は自分に合う言語を探すのが一番の近道である。
そして、言語の仕様を把握し、自分に使いこなせるのかを見極めるのが大事である。
ImageMagickでのだめ文字 5B 5D 7B 7D
0x81 ー ‐ + ±
0x82 NULL NULL NULL NULL
0x83 ゼ ゾ ボ マ
0x84 Ъ Ь к м
0x85 NULL NULL NULL NULL
0x86 NULL NULL NULL NULL
0x87 [ ] NULL NULL
0x88 NULL NULL NULL NULL
0x89 閏 云 閲 厭
0x8A 骸 馨 顎 笠
0x8B 擬 犠 宮 急
0x8C 啓 珪 鶏 迎
0x8D 梗 江 砿 閤
0x8E 纂 讃 施 枝
0x8F 充 従 旬 殉
0x90 深 疹 須 図
0x91 措 曽 捜 挿
0x92 端 綻 畜 筑
0x93 甜 転 怒 党
0x94 納 脳 倍 媒
0x95 票 評 府 扶
0x96 房 望 本 凡
0x97 夕 余 養 抑
0x98 麓 肋 NULL NULL
0x99 兌 兢 几 凩
0x9A 喙 咯 嘴 嘲
0x9B 媼 嫋 學 孺
0x9C 彈 彎 悳 怡
0x9D 拏 拆 掉 掵
0x9E 杣 枉 桀 栲
0x9F 歇 歉 毬 毳
0xE0 濕 濔 炮 烋
0xE1 畆 畩 痣 痾
0xE2 禺 秕 窖 竈
0xE3 綣 緇 縵 繃
0xE4 膽 臂 艝 艟
0xE5 藜 蘊 蛔 蛩
0xE6 觴 訃 諚 諳
0xE7 躰 躱 轆 轗
0xE8 鐚 鐓 閔 閘
0xE9 饉 饐 驅 驀
0xEA 鷦 鷯 黠 黨
0xEB NULL NULL NULL NULL
0xEC NULL NULL NULL NULL
0xED [ ] { }
0xEE [ ] { }
0xFA ∵ A _ a
0xFB A _ a
これでわからんのならもう知らん。
意見や誹謗、中傷、犯罪予告などはコメント欄にてどうぞ。
投稿から約10秒間、対応係を増やしてお待ちしております。
前へ |
次へ
コメントを見る(15)
コメントを書く
トラックバック(0)
BlogTOP
このユーザーのホーム
ログイン

ゲームランキング
Powered By FC2ブログ