« WMV にキーフレームを入れる | メイン | ピクセルを処理する関数オブジェクト »

2007年07月30日

グラフィックライブラリ:: 画像コピーにイテレーターを使うかどうか

    

画像コピー時に入力 ( src ) と出力 ( dest ) のイテレーターを渡して処理した方が良いかどうかを検討。

もし、イテレーターを渡し、そのイテレーターが1次元的なアクセスを提供するとした場合、イテレーターは、X座標、Y座標、コピー幅、コピー元(先)画像への参照の情報を持つ必要がある。
コピー幅、コピー元(先)画像への参照は、コピー領域を表すビューポートのようなオブジェクトを作れば、それへの参照で済ませられる。
ただ、それでも3つもデータを持つ必要が出来てしまう。
ピクセルを処理する関数オブジェクトへイテレーターがコピー渡しされることを考えると、あまりコピーされる情報が多いのは避けたい。

ポインタを1つだけ持つようにしようとするなら、イテレーターのクラス属性にX、Y座標などの情報を持ったクラスのリストを持ち、それへのポインタを持つようにし、イテレーターがそれらに変更を加えた時、共有を解除して新たにリストへ追加し、ポインタを変更するような作りにすれば、1つだけに出来てコピー時のオーバーヘッドは少ない。
ただ、++などでの変更時に余計な処理が要る (破棄時も)。
まあ、++される時は、イテレーターのコピーはなく1つだけになっているだろうと考えられるから、負荷増は少ないと思われる。

そもそもピクセルを処理する関数オブジェクトへイテレーターを渡す時、コピーされるのか?
ピクセルを処理する関数オブジェクトがインライン展開されるのならコピーされない可能性も高い。
ならば、何も気にせずイテレーターを渡してしまえばいいか?

イテレーターを関数オブジェクトに渡そうとした場合、ピクセルを処理する関数オブジェクトを多重に呼び出したい時に問題がある。
アルファブレンドとグレースケール化を同時に適用したいと考える。
この場合、グレースケール化した後、アルファブレンドした方が良さそうだ。
では、グレースケール化後のイテレーターが指す画像データはどこにあるのだろうか?
アルファブレンドを処理する関数オブジェクトはそのイテレーターをソース入力に取るはずだ。
中間画像を作るのはオーバーヘッドが大きすぎるので、その画素値は一時的なもののはず。
コピー先画像を指せばいいのだろうか?
たぶん、そうするとアルファブレンドは期待した結果を得られない。
同じ画像をブレンドしてしまうことになる。
ピクセルを処理する関数オブジェクトには、イテレーターではなく、画素値そのものを渡した方が良さそうだ。

そもそもなぜイテレーターを使うのか?
STL がイテレーターを使っていて、便利だしなんか良さそうだから?
イテレーターは、コンテナへのアクセス方法を統一することでアルゴリズム適用の幅を広げる。
そのためコンテナが異なっても、一部分だけでもアルゴリズムを適用しやすくなる。
では、画像の場合は?
ベクトル画像を使いたいのならコンテナは変わるかもしれないが、そうでない場合はほとんど同じではないだろうか?
少しぐらい異なっていてもインターフェイスを統一することは難しいことではなさそうだ。

アルゴリズムはピクセルを処理するもの以外に何があるだろう?
ピクセルを処理するのに相当するアルゴリズムは for_each()、transform() かな。
ソートや検索は特定のピクセルに対しては使わなさそうだ。
count() は使うかもしれない。
なんだかあんまり多くのアルゴリズムは使わなさそうだ。

画像コピーにイテレーターは使わないことにしよう。
単純コピー、拡大縮小コピー、回転(orアフィン変換)コピーなどのメソッドは分かれるだろうし、それごとのイテレーター作るのも、直接実装してしまうのも大差ないだろう。
イテレーターにするのは少し難しいし。

とか考えたのは数日前で、既にアフィン変換コピー ( 4頂点のテクスチャマッピング ) を直接実装してしまった。
でも、もう少し良い方法がありそうな気もするんだが……



投稿者 Takenori : 2007年07月30日 18:56




comments powered by Disqus
Total : Today : Yesterday : なかのひと