以前にも同じ処理について書いたけど、MSDNを眺めていたら別の方法を見つけたので試してみる。
Bitmap.Clone メソッド (Rectangle, PixelFormat) (System.Drawing)
http://msdn.microsoft.com/ja-jp/library/ms141944(v=vs.110).aspx
Rectangle rect = new Rectangle(50, 80, 200, 150); Bitmap dest = image.Clone(rect, image.PixelFormat);
コードはたった2行。ちなみに以前に書いたGraphicsオブジェクトを使う処理だと
Bitmap dest = new Bitmap(200, 150, image.PixelFormat); Graphics g = Graphics.FromImage(dest); Rectangle srcRect = new Rectangle(50, 80, 200, 150); Rectangle desRect = new Rectangle(0, 0, 200, 150); g.DrawImage(image, desRect, srcRect, GraphicsUnit.Pixel); g.Dispose();
コードは6行になる。単純計算でコーディング量は3倍。まあ、2行でも6行でも大した量じゃないけど。
処理速度の比較 – Bitmap.Cloneメソッド vs Graphicsオブジェクト
パフォーマンスが同じならコーディング量は少ないほうがいい。処理速度を検証しよう。
特定ディレクトリ中の70個のJPEGファイルをスキャンして、1つずつ読み込んで固定サイズに切り取り、別フォルダに保存し直すだけのプログラムを書いた。それぞれの方法で10回ずつ処理して所要時間を計測してみる。
using System.IO; using System.Drawing.Imaging; using System.Diagnostics; for (int i = 0; i < 10; i++) // loop for 10 times { string[] files = Directory.GetFiles(@"C:\Temp\Photo"); Stopwatch sw = new Stopwatch(); sw.Start(); foreach (string file in files) { string file2 = Path.Combine(@"C:\Temp\Photo2", Path.GetFileName(file)); Bitmap imgSrc = new Bitmap(file); Bitmap imgDst = image1(imgSrc); //Bitmap imgDst = image2(imgSrc); imgDst.Save(file2, ImageFormat.Jpeg); imgDst.Dispose(); imgSrc.Dispose(); } sw.Stop(); Debug.WriteLine("{0}: Elapsed time = {1} ms", i+1, sw.ElapsedMilliseconds); } // crop using Graphics object Bitmap image1(Bitmap image) { Bitmap dest = new Bitmap(200, 150, image.PixelFormat); Graphics g = Graphics.FromImage(dest); Rectangle srcRect = new Rectangle(50, 80, 200, 150); Rectangle desRect = new Rectangle(0, 0, 200, 150); g.DrawImage(image, desRect, srcRect, GraphicsUnit.Pixel); g.Dispose(); return dest; } // crop using Bitmap.Clone method Bitmap image2(Bitmap image) { Rectangle rect = new Rectangle(50, 80, 200, 150); return image.Clone(rect, image.PixelFormat); }
テスト結果 (処理時間)
// Graphicsオブジェクトを使った画像切り取り 1: Elapsed time = 1646 ms 2: Elapsed time = 1621 ms 3: Elapsed time = 1617 ms 4: Elapsed time = 1574 ms 5: Elapsed time = 1657 ms 6: Elapsed time = 1557 ms 7: Elapsed time = 1723 ms 8: Elapsed time = 1567 ms 9: Elapsed time = 1655 ms 10: Elapsed time = 1561 ms
// Bitmap.Cloneメソッドによる画像切り取り 1: Elapsed time = 3216 ms 2: Elapsed time = 2981 ms 3: Elapsed time = 3074 ms 4: Elapsed time = 3300 ms 5: Elapsed time = 3096 ms 6: Elapsed time = 2939 ms 7: Elapsed time = 3097 ms 8: Elapsed time = 3222 ms 9: Elapsed time = 2949 ms 10: Elapsed time = 2987 ms
結果はBitmap.Cloneを使った切り取り処理のほうが倍近く遅かった。
Bitmap.Cloneメソッドは簡単だけど処理は遅いという結論。