画像からRGBの各要素を取り出すことがあったのですが、異常に遅かったのでいろいろ比較してみました。
1280×800のBitmapからすべてのピクセルからRGBの各要素を取り出すまでの時間を比較してみました。
(CPU:Core2DuoT7200/Memory:4GB)
手法 | 時間 |
GetPixel | 1.8356103 |
GetPixel2 | 1.5895904 |
LockBits | 0.0062316 |
unsafe | 0.0024599 |
※GetPixel2はWidthとHeightを一時変数に代入し、高速化を図ったもの
こうしてみると、WidthプロパティとHeigtプロパティにアクセスするだけで結構時間がかかることがよくわかります。あと、LockBitsとunsafeの時間の違いはMarshalCopyの処理時間なのかな?
(以下ソースコード)
GetPixel
for (int i = 0; i < bitmap.Width; i++)
{
for (int j = 0; j < bitmap.Height; j++)
{
var color = bitmap.GetPixel(i, j);
int r = color.R;
int g = color.G;
int b = color.B;
}
}
GetPixel
int width = bitmap.Width;
int height = bitmap.Height;
for (int i = 0; i < width; i++)
{
for (int j = 0; j < height; j++)
{
var color = bitmap.GetPixel(i, j);
int r = color.R;
int g = color.G;
int b = color.B;
}
}
LockBits
BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height),
ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
int width = bitmapData.Width;
int height = bitmapData.Height;
byte[] bytes = new byte[bitmapData.Stride * bitmapData.Height];
Marshal.Copy(bitmapData.Scan0, bytes, 0, bytes.Length);
int index = 0;
int nResidual = bitmapData.Stride - width * 3;
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
int r = bytes[index + 2];
int g = bytes[index + 1];
int b = bytes[index];
index += 3;
}
index += nResidual;
}
bitmap.UnlockBits(bitmapData);
unsafe
BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height),
ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
int width = bitmapData.Width;
int height = bitmapData.Height;
int nResidual = bitmapData.Stride - width * 3;
unsafe
{
byte* p = (byte*)(void*)bitmapData.Scan0;
for (int y = 0; y < height; ++y)
{
for (int x = 0; x < width; ++x)
{
int r = p[2];
int g = p[1];
int b = p[0];
p += 3;
}
p += nResidual;
}
}
bitmap.UnlockBits(bitmapData);
0 件のコメント:
コメントを投稿