先日、Flashのお絵かきツールで描いた絵を、セカンドライフのボードに表示できるSLらくがきボードというのをリリースしました。実際のお絵かきツールは、こことかで見れます。
このツールではアンチエイリアスのON、OFFが可能になっていますが、実は先に実現可能かどうかは考えたわけではなく、そのうち出来るようにするからーとアナウンスして、とりあえずリリースしてしまったものなのです。
後から調べたところ、ニコニコ大百科のお絵カキコや、Sumo Paintなどでも、アンチエイリアスOFFは実装されてないことを知って、出来ないのかなと慌てふためいたのですが、色々試したところなんとか出来たので、そのやり方を書いてみようと思います。
本格的な説明に行く前に、私が作ったお絵かきツールのキャンバスの構造の説明から。キャンバスは、もろもろの理由により以下のようになっています。
これは、5枚のレイヤーがあって、3枚目が選択されている場合の図です。3枚目の前に描画用のレイヤーがあり、ここへ描いた線や図形などを実際のレイヤーに、BitmapData.drawメソッドで転写する仕組みになっています。
Bitmap.drawメソッドの引数はいくつかありますが、ColorTransformクラスを渡すことで転写時の色合いや透明度を変化させることができます。ColorTransformのフィールドには、alphaOffsetという項目があり、これを255に設定すれば転写時の非透明度は常に最大になります。最初は、これでいいんじゃねと思ったんですけど、なぜかアンチエイリアスの効いた線になってしまいました( ̄□  ̄ ||
// 実際のレイヤーキャンバスのImageコントロールを取得
var image:Image = getImage();
// ImageコントロールからBitmapDataを取得
var bitmap:BitmapData = image.source.bitmapData;
// Bitmapへ描画用レイヤーの内容を転写
bitmap.draw(getDrawLayer(),
null,
new ColorTransform(1, 1, 1, 1, 0, 0, 0, 255), // 透明Offset255
null,
null,
false);
で、試行錯誤して辿り着いた結果が次のヤツです。まず一時的なBitmapDataへ描画用レイヤーの内容を転写し、その一時BitmapDataを実際のレイヤーキャンパスへ再転写しています。これでなぜかうまくいきました( ̄∇  ̄ )
// 一時ビットマップを作成
var tmpBitmapData:BitmapData = new BitmapData(width,
height,
true,
0x00FFFFFF);
// 描画レイヤーの内容を一時ビットマップへ転写
tmpBitmapData.draw(getDrawLayer(),
null,
null,
null,
null,
false);
// 実際のレイヤーキャンバスのImageコントロールを取得
var image:Image = getImage();
// ImageコントロールからBitmapDataを取得
var bitmap:BitmapData = image.source.bitmapData;
// Bitmapへ一時BitmapDataの内容を転写
bitmap.draw(tmpBitmapData,
null,
new ColorTransform(1, 1, 1, 1, 0, 0, 0, 255), // 透明Offset255
null,
null,
false);
仕組みとかどうなっているのかは、よく分かりません。描画用レイヤーは実際に画面に描画されるので、その際になにか特別な処理でもされているんでしょうか?
まあ、とにかくアンチエイリアスを切りたいときは、一時BitmapDataに転写しとこうってことですね。しかし、Flashでお絵かきツールを作ってる人って日本で100人いるのかな? とてつもなくニッチなネタになってしまった気がします。