비트 맵 클래스에는 X 및 Y 좌표가 지정된 비트 맵에서 픽셀의 색을 반환하는 GetPixel 메서드가 포함되어 있습니다. 한 가지 기술은 비 - 화이트 픽셀이 존재하는 가장 낮은 X 및 Y 좌표를 결정하기 위해 데이터의 행 및 열을 이동하는 것일 수 있습니다. GetPixel을 호출하는 것이 다소 느리기 때문에 이미지가 작거나 성능이 중요하지 않은 경우이 기술이 적합합니다.
또 다른 방법은 Bitmap 이미지 데이터를 byte []로 가져온 다음 배열에서 바이트를 걷어 흰색 픽셀이 아닌 위치를 결정하는 것입니다. 이 접근법은 주어진 비트 맵 유형 (예 : 32 비트, 24 비트, 1 비트 등)에 대해 바이트가 배치되는 방식에 대한 약간의 지식이 필요합니다.
비트 맵의 바이트를 가져 오려면 비트 맵의 LockBits 메서드를 호출하여 비트 맵의 영역을 잠그고 BitmapData 객체를 가져옵니다. 그런 다음 BitmapData 객체의 Stride 및 Height 속성을 사용하여 비트 맵을 포함하는 데 필요한 바이트 배열의 크기를 결정합니다.
필자는 타원의 위치를 감지하기 위해 만든 몇 개의 테스트 이미지에서 빠르게 작동하는 것으로 보이는 다음 방법을 채우고 테스트했습니다.
private Point DetectLocation(Bitmap original)
{
Bitmap source = null;
// If original bitmap is not already in 32 BPP, ARGB format, then convert
if (original.PixelFormat != PixelFormat.Format32bppArgb)
{
source = new Bitmap(original.Width, original.Height, PixelFormat.Format32bppArgb);
source.SetResolution(original.HorizontalResolution, original.VerticalResolution);
using (Graphics g = Graphics.FromImage(source))
{
g.DrawImageUnscaled(original, 0, 0);
}
}
else
{
source = original;
}
// Lock source bitmap in memory
BitmapData sourceData = source.LockBits(new Rectangle(0, 0, source.Width, source.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
// Copy image data to binary array
int imageSize = sourceData.Stride * sourceData.Height;
byte[] sourceBuffer = new byte[imageSize];
Marshal.Copy(sourceData.Scan0, sourceBuffer, 0, imageSize);
// Unlock source bitmap
source.UnlockBits(sourceData);
int sourceIndex = 0;
int pixelTotal = 0;
int height = source.Height;
int width = source.Width;
int threshold = 255 * 3;
int minX = width;
int minY = height;
// Iterate lines
for (int y = 0; y < height; y++)
{
sourceIndex = y * sourceData.Stride;
// Iterate pixels
for (int x = 0; x < width; x++)
{
// Compute pixel brightness (i.e. total of Red, Green, and Blue values)
pixelTotal = sourceBuffer[sourceIndex + 1] + sourceBuffer[sourceIndex + 2] + sourceBuffer[sourceIndex + 3];
if (pixelTotal < threshold)
{
minX = Math.Min(minX, x);
minY = Math.Min(minY, y);
}
sourceIndex += 4;
}
}
return new Point(minX, minY);
}
BTW, 안전하지 않은 코드 및/또는 포인터가 신속하고 효율적으로 작동하지 않아도됩니다. –