aa01.cpp は静止画像にアンチエイリアスを施すルーチンです。しかしちょっと問題もあるんですよね。この問題はアンチエイリアスを実装するアルゴリズムに強く依存する問題であり,このようなリソースを残す意味は多分に希薄かと。でも書いてしまったものは仕方ありません。
使用方法はあまり難しいものではなく,aa01.h を見れば分かるように,実際に公開されている API は anti_alias() ただ 1 つです。
int anti_alias(
int threshold,
unsigned char *dst,
unsigned char *src,
int bpl,
int height,
int depth );
anti_alias() は元画像から輝度情報を抜き出し,任意のピクセルと隣のピクセルとの輝度を比較してアンチエイリアスを施すべきかどうかを決定します。threshold は,どれくらい輝度が離れていればアンチエイリアスを施すべきかという閾値を 0〜255 で指定します。dst と src は,例えば Win32 API の ::CreateDIBSection() で割り当てられるメモリ領域によく適合します。malloc() などで独自に領域を割り当てる場合,必ず横 1 ラインのサイズは“ 4 の倍数”バイトでなければなりません。画素深度 24 ビットで横 3 ドットの画像の場合,横 1 ラインに必要なサイズは 9 バイトですが,あえて 12 バイトを割り当て 4 の倍数に揃えます。dst と src は同じサイズである必要があります。anti_alias() は,それぞれの BPL および高さが同じであると仮定します。dst と src が同じ場所を指している場合,アンチエイリアスは正常には行われない可能性があります。anti_alias() を使う前に,もしかしたら aa01.cpp を書き換える必要があるかもしれません。
static
unsigned char *get_luminances( ... ) {
...
// ここ
unsigned char *luminances = (unsigned char *)malloc( width * height );
...
static
void release_luminances(unsigned char *luminances) {
free(luminances); // ここ
}
malloc() および free() を用いない場合,適切な関数に置き換えます。
OK,もしあなたが今までにアンチエイリアスのコードを見た事も書いた事も無いならば,今日はそれなりに良さげなコードを見た最初の日です。そうではなくこれまでに何度か書いた事のある人ならば,即刻退去願います。恥ずかしいんで。
このコードでアンチエイリアスを行うと,次のような問題が発生します。このように二又に分かれた線分にアンチエイリアスを施すと,
こんな結果が得られます。
このうち,赤で囲んだ部分で・・
なんだか非理論的な変化をしているのが気になって仕方ありません。これは anti_alias() が次のように処理を行うからです。まず anti_alias() は次のような傾きのある線分に気づきます。
そこで,次のようにグラデーションを描画します。
次に,下のような線分にも気づきます。
このようなグラデーションを描画します。
これを合成する事で最初の図のような奇妙なグラデーションが生成されるわけです。これを解決するには色々と方法が考えられますが,どの方法を採用するかは検討中という事で。