2011年4月28日木曜日

ImageMagick PSD続き、PNGをインデックスカラーで透過

  • PSDをレイヤ単位で分割して重ね合わせること(-flatten)することで再構成するような話をこの間書いたが。
  • あれは嘘だ
  • というかそれだけでは元のレイヤの高さなどが反映されてしまうため、出力サイズが想定のものにならない。なので(-flatten)した後に画像サイズに(-crop)をかけてあげる必要がある。
  • 画像の元サイズが480x480で100x100に出力したい場合はこんな感じになった。
  • 当然前の記事を参照して、レイヤごとのオフセットはあわせること。
  • convert -page +0+0 hoge.psd[1] -page +0+0 hoge.psd[2] -page +0+0 hoge.psd[3] -flatten -crop 480x480+0+0 -geometry 100x100 +repage 100x100 result.gif
  • (追記)レイヤの大きさに影響されないようにするためには-cropの後にさらに+repageして仮想画面のサイズを修正する必要がある
  • これでレイヤのサイズが不均等でも正しく出力されるようになる。
  • -cropしてから-geometryでリサイズする、つまり順番が重要になるわけです。
  • ここからPNGの話。
  • アルファ付きのPNGをリサイズして出力すると。アルファチャネルが崩れる問題がImageMagickにはある。というかなんかいかにもメモリリークしてますよーという感じのゴミが画像にのっかってしまいいかにも見苦しい状態に。
  • というかPNGまわりの実装がImageMagickは非常に怪しく、バージョンによっては何もしなくても、出力時にゴミが入ってしまうようだ。(2011年4月時点で6.6.8に当該バグが存在した、アルファ周りのバグは最新版でも存在)
  • ImageMagickの更新ログを見るとPNGがらみの問題が結構多い。
  • まだまだ未成熟なんだね
  • まあとにかくそんな感じでアルファ付き(透過)、PNGを正しく出力するにはどうすればいいか。いろいろオプションがあるので試してみたがこれといった解は見つからなかった。明らかにバグ。
  • 単なる一色抜きの透過PNGが欲しいだけなのに、8bit Alpha付きのPNGでImageMagickは処理しているのだ。
  • いちばん簡単な解決法。
  • GIFで一旦出力して、(-transparent #XXXXXX)を指定しPNGに変換する。
  • こうすることでImageMagickにおけるPNGのアルファチャネル由来のバグは回避できた。
  • こういう情報をバッドノウハウといいます。

2011年4月27日水曜日

ソニーの個人情報流出

  • PS3は堅牢なプラットフォームだったけど、秘密鍵をハックされて以後一気にやられてしまったようだ。
  • 半年もたってないよね。
  • 土台完璧なプログラムなんてないのだから。ゲームなら尚更のこと。バグとセキュリティホールは存在するしハッキングはされるものなのだ。
  • まあ今回のようなケースでは、シッペ返しを食らうのは当然だなあ。という文化や空気感が僕の知る限り昔はありました。今はそういう人たちは声をひそめてるのだろうか。
  • むしろあの文化圏の人たちにはソニーとか今騒いでる人たちが異物に見えてると思うよ。善悪とか数の大小はさておき。
  • スパムの流量とか、クラウドハッキングとか持ち出すまでもなく、ネットは依然そういうお行儀の悪い人たちのものなのである。
  • そこに繋ぐからにはまあ覚悟して繋ぐべきですよね。ルートキーが割れてからも、ハッカーとやりあい続けたのは、全裸で住民をディスりながら、ヨハネスブルグの路地裏をうろついているようなもので。ヤられた側に責任がないかどうかは…。
  • 一般常識として拳銃突きつけられたら手をあげるべきです。今年頭からの経緯を見ても、爆発物持った相手にソニーは威圧的すぎた。つまり渉外担当があんまりにも無能すぎた。それに尽きるんだと思います。
  • 責めるとしたらセキュリティリスクの報告に対して対応に当たった人間
  • これが、いかにも日本的な威圧感漂うアホだったんだろうなと妄想
  • よし、周りにいた警備員がなんとか暴漢を観念させたとしても。それを見て周囲が今度は爆発物を投げつけてくる。今度は覆面をして。
  • 辿る道筋が分かってるからITを周知してる会社は弱腰ですし、最初の暴漢に感謝すらする。その場所が危険であることをわざわざ教えてくれてるのだから。
  • 願わくばまあこうしたことが、規制の方向に進まずに、社会がよい方向に進むようにと思う。

ImageMagickのPSDの扱い方

  • ImageMagickにおけるPSDの扱い方
  • PSDのレイヤを比較的正しく扱ってくれるフリーウェアはこれとGIMPくらいでPaint.NETは論外でした。多分元ソースをゲーム用のとあるライブラリからとってるであろうやつはなんかダメそう。
  • Photoshopではレイヤに特殊効果がつけられるのですが、これが無視されてしまう。
  • コマンドラインが結構いろんな組み合わせでききいれてくれるので混乱するですね。
  • 今日の嘘情報 : レイヤ付のPSDはImageMagickで出力するとレイヤが全て書き出されるので-flattenのオプションをつけると正常に出力されるよ。これは嘘これで成功するケースは偶然レイヤがみんな同じサイズで、偶然移動されてないだけのことだ。ああ、あとレイヤの特殊効果もこの書き方だと消滅します、よいとこなしです。
  • PSDをかたっぱしから流し込んでためしてみればわかるけどレイヤのサイズがまちまちだとレイヤの重ね合わせも出力サイズもずれてしまって悲しいことになる。
  • レイヤ付のPSDは特殊なシーケンスとして扱われる。hoge.psd[0]がレイヤをすべて結合した画像。[1]番以降は各レイヤを底から見ていく。アニメーションGIFと同様な感じです。
  • なので正常に重ね合わせが行われた、画像をPSDから出力したい場合は単に
  • convert hoge.psd[0] -geometry 100x100 moge.gif
  • と書けばよい。
  • 理由があってレイヤを-flattenで重ね合わせたいときはもう少し複雑。
  • Identify hoge.psdからレイヤの枚数と、各レイヤのオフセットを取得。出力の真ん中くらいにある100x100-10+20の-10+20の部分。
  • identify -format %X%Y hoge.psd[1]
  • という感じで取得可能、で-pageで各レイヤにオフセットを指定してあげると正しい位置にレイヤが配置される。全てのレイヤの情報が欲しければ下のように書けばいい
  • identify -format %X%Y, hoge.psd
  • こう書くことでCSV風に出力されて、スクリプトの中で扱いやすくなる。カンマが重要
  • でここで得た出力が以下のようなものの場合
  • +0+0,+0+0,-100+50,+163+22
  • このようにconvertで全てのレイヤを結合してあげれば正しく重ね合わされた画像が得られる。
  • convert -page +0+0 hoge.psd[1] -page -100+50 hoge.psd[2] -page +163+22 hoge.psd[3] -flatten result.gif
  • この際Phostoshopレイヤの特殊効果はなくなってしまうことに注意が必要。
  • (追記)これだけでは情報が不十分なのでこちらのページも参考にしてください
  • (追記)ImageMagickでPSDのレイヤを何かしようという人がどれだけの数いるかは疑問ですが

2011年4月21日木曜日

WindowsForms + C# : ツリービュー、ノードの順番入れ替え

  • ツリービューにおけるノードの順番の入れ替え。構造化テキストエディタとかだと順番重要。
  • XMLで書いたフィルタに対するエディタを作成していて必要になったので。
  • ソートはあるが、順番の入れ替えは、機能的に準備されてない。
  • ウェブ眺めて情報がないわけではなかったが、全部要素を消してループ書いて入れ替えとか面倒じゃないか
private void MoveTreeNodeInSiblings(Boolean upward)
{
//要素をCloneしてコピーすると比較的簡単に入れ替えられる//

TreeNode nodeClone = (TreeNode)treeViewFolder.SelectedNode.Clone();
TreeNode node = (TreeNode)treeViewFolder.SelectedNode;
TreeNode fowardNode = upward?node.PrevNode:node.NextNode;

if (node.Parent == null) {
MessageBox.Show("最上位の要素の入れ替えはできません");
return;
}

//参照のコピー
TreeNode ParentClone = (TreeNode)node.Parent.Clone();
IEnumerator en = ParentClone.Nodes.GetEnumerator();
TreeNode ParentRef = node.Parent;

int nodeHash = node.Tag.GetHashCode();//タグにデータが入ってること前提
int fowardHash = fowardNode.Tag.GetHashCode();

node.Parent.Nodes.Clear();//入れ替えのために消す

treeViewFolder.Visible = false;//描画対策
//基本的にクローンした要素に差し替える工程
while (en.MoveNext()) {
TreeNode tn = (TreeNode)en.Current;
if (fowardHash== tn.Tag.GetHashCode()) {
if (upward) {
ParentRef.Nodes.Add(nodeClone);
ParentRef.Nodes.Add(tn);
} else {
ParentRef.Nodes.Add(tn);
ParentRef.Nodes.Add(nodeClone);
}

} else if (nodeHash == tn.Tag.GetHashCode()) {
/*Skip*/
} else {
ParentRef.Nodes.Add(tn);
}
}
treeViewFolder.Visible = true;
treeViewFolder.SelectedNode = nodeClone;
treeViewFolder.Focus();
}

2011年4月14日木曜日

FLVPlaybackとFLVPlaybackcaptioning

  • 忙しい忙しい。
  • FLVPlaybackとFLVPlaybackCaptioningを最近使う機会があった。
  • 環境はCS3。入れ替えてないだけ。
  • 字幕とかなんだか、オーバーレイするビデオプレイヤーは作ってるが、Flex SDKでやってたりで標準のコントロールを使うのははじめてかも。
  • FLVPlaybackとキャプションを使用する上で何点かあまり情報がないTIPS
  • FLVPlaybackCaptioningを用いた字幕はシーク時に開始地点(ttmlでいうところのbegin属性で指定された時間)以外の所に再生ヘッドを動かすと表示されないが、CaptioningコントロールのshowCaptioningを一旦falseにしてtrueにすると表示される・・・・え?
  • 具体的には 「caption.showCaptions = false; caption.showCaptions = true;」というのをFLVPlaybackのseekイベントのハンドラに仕込んでやればいい。
  • シークバーのつまみから手を放すと表示される。
  • 理屈は分かるが納得いかない。
  • この問題のせいで糞認定されてるケースも多分あるよな。
  • FLVPlaybackのコンポーネントであるところの、シークバーとボリュームバーの実装が悪い。
  • 両方同時に画面におけないというバグがあったらしい。まあそれには対面していないのでさておき。
  • 最悪なのは「つまみ」のムービークリップがドキュメントの直下にaddChildされているところ。seekBarのインスタンスからつまみにアクセスする手段はない。
  • たとえば、操作できないように半透明のマスクをかぶせたりするようなことをする場合、このシークバーコンポーネントがあるとつまみが、画面に操作できる状態で表示されてしまう。
  • ドキュメントの子要素を列挙すると「つまみ」のインスタンスがわかりやすい名前で存在しているので、取得してvisibleをfalseにしてあげればとりあえずは解決するように見えるが・・・
  • 上記のハックでseekBarの「つまみ」を消すことはできるが、volumeBarに関しては不可能だった。消した後、visible = trueとしても再度表示されなくなる。
  • なので用件に応じてvolumeBarは自作すること。まあそんなたいしたものでもないので。
  • FLVPlaybackには機能としてミュート機能が存在するが、プロパティやメソッドでアクセスする手段はない。仮に画面上に配置したミュートボタンにMouseEventを投げて押してあげると使える。
  • いろいろ細かいところに難点はあるものの乗り越えられれば出来のよいコンポーネントだと思います。