リフレクション
[C#,VB.NET]Graphics.DrawImage(image,0,0)の落とし穴
VC#Express2008で.NET Frameworkのライブラリ・ソースへステップイン
これらのエントリーは実はちょっと確認したいことがあった流れで書いてました。
確認したかったのはGDI+の処理速度です。
具体的には「同じ結果を導く異なる描画方法の処理速度差」になると思います。
もちろん速い方を選びたいのが人情でしょう。
今日は上の流れで見つけたある2つの同じ結果を導く違う描画方法の比較をしようと思います。
●比較対象処理
Pixel-to-Pixel処理の一種であるグレースケール化です。
方式1:Bitmap.LockBits/Bitmap.UnlockBitsで画像の画素情報に直接アクセス
方式2:System.Drawing.Imaging.ColorMatrixによる色の行列変換
●テストプログラム詳細
ダウンロード:C# - GrayScaleSpeedTest.zip
共通部分
・画像はjpg画像に限定し24bitピクセルフォーマットでの比較を行う。
・まずファイルオープンダイアログでjpgを選択
・フォームクラスのローカル変数originalBmpに画像を保管
・各方式はメニューで選択
・選択された方式にoriginalBmpを引き渡しピクチャボックスへ結果を描画させる
方式1部分
・junki氏の画像処理ライブラリ「ImageUtils」(※1)のGrayScale24()を使用(このメソッドは内部でBitmap.LockBits/Bitmap.UnlockBitsを使用してグレースケール化を行う)
・引数にBitmapの参照を渡し返値は参照に上書きして返ってくるので、方式1開始部分で一旦originalBmpのクローンを作ってGrayScale24()で処理し返値をピクチャボックスへ設定する。
※1:Image Processing Utilities for C#2.0 (VC# 2005) Copyright junki, Jan, 2006 -
junki氏 HP:http://junki.lix.jp/ ImageUtils:http://junki.lix.jp/archives2/ImageUtils.lzh
方式2部分
・ColorMatrixに次の行列を設定
[ 0.299, 0.299, 0.299, 0.0, 0.0 ]
[ 0.587, 0.587, 0.587, 0.0, 0.0 ]
[ 0.114, 0.114, 0.114, 0.0, 0.0 ]
[ 0.0, 0.0, 0.0, 1.0, 0.0 ]
[ 0.0, 0.0, 0.0, 0.0, 1.0 ]
・ImageAttributesを作成し行列を設定
・変換用にoriginalBmpと同サイズ、24bitピクセルフォーマットのビットマップ作成
・Graphics.DrawImageにImageAttributesを渡し変換用ビットマップに対してグレースケールで描画を行う。
・変換用ビットマップをピクチャボックスへ設定する。
●結果
フリー写真素材(※2)をお借りして方式1と方式2でそれぞれ100回ずつ変換を行った。
以下はそれぞれの方式のかかった時間を5回ずつ表示させています
ColorMatrixを用いた方が速いという結果になりました。
※2:ren氏HP:http://sk-d.a-thera.jp/
ダウンロード:http://www.photolibrary.jp/profile/artist_244_1.html
●実は納得していなかった
私はこのテストではColorMatrixの優位を証明できていないと思っています。
jpgが悪いとか誤字とか行列の値が違ってるとかループ回数が少ないとか多いとかではありません。
このテストでもある条件下では私も十分に納得すると思います。
でも今回はその条件ではないので納得していないわけです。
ではある条件とは一体何のことでしょう?
#うーーん。実は引っ張るほど大した話じゃないかもですが・・・
この続きは明日か・・・明後日かもです。
色々と考えて楽しみにしててください。
#聞くと本当に大した事じゃないので怒らないでくださいね。