2006/12/20(水)FULLWIDTH TILDE問題

どこかで聞いたことはあったけど始めて遭遇。

WindowsのShift-JIS <-> UTF-8の変換表が本来の規格と異なるため、アプリ側の変換表で文字化けたりする問題。
VirtualDubのjobsにまとめてファイルを投げるRubyスクリプトを以前書いた。VirtualDubはUTF-8でファイル名を扱うのだが、このとき"~"を含むファイル名に対して、RubyのkconvでSJIS->UTF-8変換をしていたら"~"はWAVE DASHと解釈され\xe3809cに。しかしこれをVirtualDubからWindowsに投げると、"~"(FULLWIDTH TILDE)に戻せない。ということで「ファイルが見つかりません」となり問題が発生。

しかしコードの違いだけならまだしも割り当てられている文字そのものが違うとはまた面倒くさい……

ということで、Windows上の"~"の扱いである\xefbd9e(FULLWIDTH TILDE)に変換しないといけない。とりあえずRubyにはNKFがあるので、

NKF.nkf('-w --cp932', "~")

で変換すれば良し。なお、nkfのオプション指定はパースが厳しいようで、short optionは先に、先後に余計な空白を挟まないようにしないと上手く解釈されなかった(多分)。

今後、Windowsのファイル名をUnicodeで扱う際には念を入れてチェック。他に気をつける場面はなにがあるだろう。ファイル内部の表記はずれるのかな。Winアプリで"~"と表示されているとして、アプリ側がどのコードで保存し、表示でいじってるかとかはファイルの中を見ないと分からない?? 怖いなあ。

2006/08/08(火)AfterEffectsとかPhotoShopとかを自動で

あまり時間がないので雑メモだけ。

FI/FOがあるだけの簡単なテロップを自動制御で大量生産するのが今回の目的。最終的にはPhotoShopをOLEオートメーションでドライブしてpsdを大量に吐かせた後、AfterEffectsはjavascriptの自動制御でフッテージ差し替え->レンダリングを繰り返すことで実現できたようだ。

まずはPhotoShop側から。

PhotoShop/Illustrator/InDesignなんかはOLEオートメーションがしっかり実装されていて、OLEが使える言語からなら色々操作が可能だ。今回はいつも通りRubyでバリバリ.psdを吐かせてみた。

基本スタートはいつものこちら。

http://jp.rubyist.net/magazine/?0003-Win32OLE
ただ、結局の所僕の腕では複雑なアプリケーションのクラス構造やら、引数の見当をつけるのはほとんど不可能に近い。オブジェクトインスペクタならぬ、オブジェクトブラウザで覗いてみたところで、"Option"という引数名に文字列が来てたらもうそこでパンクしてしまう。全ては対象アプリケーションのリファレンスの充実度次第。

photoshopはインストールフォルダのどこを探してもリファレンスらしきものが出てこない。そこで、

http://codezine.jp/a/article.aspx?aid=406
にあるように、英語版AdobeサイトのDownloadページから、

Photoshop 7.0 Scripting plug-in v.1.0.2a

を取ってくる。これに付いてるリファレンスがきっちりしていて使える。これがなかったら何も出来なかった。

AfterEffectsの方は、少なくとも所持している6.0ではOLEオートメーションは効かないようにみえる。スクリプトそのものは動くので、vbsかjsで書くことになる。ちゃんと理解してないのかもしれないが、AfterEffectsのscript部分はレンダリングの制御のみを目標に考えられているようだ。どうもコンポの中身を弄れるようには見えない。だからレンダーオートメーション? 中身はExpressionで弄れるのだろうか?

ともかく、今度は付属のドキュメントが歯抜け過ぎで肝心なことが書いていない。結局以下のサイトに頼った。

http://hpcgi2.nifty.com/Nekomata/nekojyarashi/wiki.cgi?ObjectList01
これ読まなかったらレンダーキューへのつっこみ方もよく分からなかった。感謝。

http://www.openspc2.org/reibun/AfterEffects6.5/
おまけ。でもこっちはドキュメントに書いてある範囲をそんなに出てないから、あんまり役に立たないかなあ。

2006/05/03(水)Perl

久々に触ったけど、Perl難しいよPerl。

Perlのポケットリファレンスどっかいっちゃったので、使ったWebページをメモ。

http://www.rfs.jp/sb/perl/index.html

http://www2u.biglobe.ne.jp/~MAS/perl/ref/index.html

http://www.nwt.jp/document/perlfunc/index.htm

http://pub.cozmixng.org/~the-rwiki/rw-cgi.rb?cmd=view;name=%A5%B9%A5%AF%A5%EA%A5%D7%A5%C8%B8%C0%B8%EC%A4%CE%C8%E6%B3%D3#header-navi
[わからないこと、いやなこと]

・$x と @x が違う変数なのはもちろんいいんだけど、@xの要素にアクセスするときに$x[]なのがちょっと気持ち悪い。

が嫌。なぜここだけ<>?

・あとスカラーで評価されるタイミングがよく分からない。

・破壊的代入ばっか……

・クラス・構造体の実装が無理しすぎに見える。
改めて思う、Rubyは楽ね。

2006/05/03(水)GD::Graphのあれこれ(Perl)

あまり他で書いてないことをいくつか。

GD::Graphの生成画像にイメージマップを貼る


GD::Graph::Mapを使う手もあるがどうも使い勝手が悪い。そこでhotspot()メソッドを使う。
use GD::Graph::points;
my $graph = GD::Graph::points->new(400,300);

@data = (
	['1st', '2nd', '3rd'],
	[1, 2, 3],
);

my $image = $graph->plot(\@data) or die;
my @ret = $graph->get_hotspot(1);
for(my $i = 0; $i < @ret; $i++) &#123;
	print "<area shape=$ret[$i][0] Coords=$ret[$i][1],$ret[$i][4],$ret[$i][2],$ret[$i][3]>\n";
&#125;
こんな感じで。第1引数はデータ系列番号(1始まり)、第2引数はデータ系列中のデータ番号(0始まり)。共に省略可。

ソースをざっと見た限りでは、生成したグラフのタイプによってtop, bottom, left, rightがどの順で帰ってくるか違ってるような気がする。

プログラム作成時にテストした方がよい。
なお、どうでもいい話であるが、このメソッドいつも「ホッツポット」と読んでしまう。なんでだ?

numerical X(x軸を数字として扱う)


GD::Graphは基本では全てのXを見出しとして等価に扱う。

だが、散布グラフや1つの列に2つ以上のデータをプロットする場合など、X座標を数字として扱いたい機会は多い。

GD::Graphのマニュアルにあるとおりこの機能は本来はunsupportedである。従って、ちょっとやり方が複雑。


  1. x_min_value, x_max_value, x_tick_numberの3つを設定する

  2. データ系列が3つ以上の値を含む

  3. x軸のデータが全て数字


この3条件を満たすときに数字として扱ってくれるようだ。
use GD::Graph::points;
my $graph = GD::Graph::points->new(400,300);

@data = (
	[1 ,1, 10],
	[1, 2, 3],
);

$graph->set(
	x_min_value => 0,
	x_max_value => 30,
	x_tick_number => 10,
);

my $image = $graph->plot(\@data) or die;

open(OUT, ">test.png") or die;
binmode OUT;
print OUT $image->png();
close(OUT);
setメソッド中の3行はどれをコメントアウトしても表示がおかしくなると思う。

グラフ座標を画像のピクセル座標に変換


val_to_pixel()メソッドを使う。本来プライベートメソッドであるべきものを呼んでる気がするけども。
use GD::Graph::points;
my $graph = GD::Graph::points->new(400,300);

@data = (
	['1st', '2nd', '3rd'],
	[1, 2, 3],
);

my $image = $graph->plot(\@data) or die;
my $green = $image->colorAllocate(0, 255, 0);

my @p1 = $graph->val_to_pixel(1, 1);
my @p2 = $graph->val_to_pixel(3, 3);
$image->line(@p1, @p2, $green);

open(OUT, ">test.png") or die;
binmode OUT;
print OUT $image->png();
close(OUT);
(1,1)から(3,3)の間に直線を引く。numerical Xにした場合でもちゃんと動くようだ。

なお、普通の解説とかサンプルは下記参考サイトが詳しい。

お、Rubyにラッパーあるね。まだ触って無いけど。
[マニュアル]

http://search.cpan.org/~bwarfield/GDGraph-1.4307/Graph.pm
[サンプル]

http://x68000.q-e-d.net/~68user/webcgi/gd-graph.html

http://www.linkclub.or.jp/~ma3ki/webutil/gdgraph/howtograph.html

2006/02/24(金)Rubyでコンソールから1文字入力

なつかしのC言語だとgetch()あたりで簡単に出来るコンソールからの直接1文字入力。Rubyの標準機能だとどれを使ってもEnterを押されるまで読み込めない。別に我慢すればいいような話なのだが、ちょっと挑戦。

・解決案1(不採用) 添付ライブラリcursesを使う。Winでもunixでも動くには動きそうだが、表示とかが機種依存ぽいので止め。

・解決案2(採用) Win32API+crtdll.dllを使う。もちろんwin32限定だが、その範囲に限れば最も機種依存度低そう。(msvcrt.dllよりもcrtdll.dllの方が汎用性高いという認識で合ってるよね?)

ということで解決案2でGO。

こんなふうに書いてみた。
require 'Win32API'

func_getch = Win32API.new('crtdll.dll', '_getch', 'v', 'i')

str = "Do you like skate? [y/N]\n"
print str

while true do
	x = func_getch.call.chr.downcase
	
	case x
	when 'y'
		#yesの時の処理
		print "Ok!\n"
		break
	when 'n', "\r"
		#noの時の処理(デフォルト)
		print "Terrible!\n"
		break
	when "\C-c"
		#getchでコンソールを奪うと中断出来ないので
		exit
	else
		print str
	end
end
如何にも古い人のコードだが気にしないで欲しい。

Win32API->crtdll.dll経由で_getchを呼び出す。_getchはエコーしないのであとは入力された文字で処理を分けてやるだけ。

意外と簡単に書けたけど…… こんなの使うのかな?

[参考URL]
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-list/6991
OK キャンセル 確認 その他