我有幾個圖像,我想放在窗體中。圖像本身是85 x 85.每個圖像都有一個白色背景,其中包含一個可以位於圖像任意位置的大小不等的圓柱體對象。.NET圖像圖像
例如:
圖片1:85瓦特X 85H具有在氣缸圖像:從左上角
圖像2(25,35):85瓦特X 85H具有在氣缸圖像:(28, 42)從左上角
我想知道是否有可能以編程方式確定與.NET圖形庫的位置(25,35)或(28,42)。
基本上我想要做的是將圓柱體重新定位到一個固定的座標,從左上角說(10,10)。
我有幾個圖像,我想放在窗體中。圖像本身是85 x 85.每個圖像都有一個白色背景,其中包含一個可以位於圖像任意位置的大小不等的圓柱體對象。.NET圖像圖像
例如:
圖片1:85瓦特X 85H具有在氣缸圖像:從左上角
圖像2(25,35):85瓦特X 85H具有在氣缸圖像:(28, 42)從左上角
我想知道是否有可能以編程方式確定與.NET圖形庫的位置(25,35)或(28,42)。
基本上我想要做的是將圓柱體重新定位到一個固定的座標,從左上角說(10,10)。
Bitmap類包含一個GetPixel方法,該方法根據其X和Y座標返回位圖中像素的顏色。一種技術可能是遍歷數據的行和列以確定存在非白色像素的最低X和Y座標。如果圖像較小和/或性能不是主要考慮因素,則此技術已足夠,因爲調用GetPixel相當慢。
另一種方法是將位圖圖像數據轉換爲字節[],然後遍歷數組中的字節以確定非白色像素的位置。這種方法需要了解給定位圖類型(例如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);
}
我不知道這個圓柱體是多麼複雜(作爲一個形狀),但是你可以穿過所有的像素,檢查哪個行和列可以找到第一個非白色像素。
AFAIK,圓柱體已經平坦地下到圖形大概由一些Photoshop應用程序。 – coson 2009-07-23 18:31:52
好吧,無論如何,通過掃描行/列,找到第一行和最後一行/列,然後只是複製這樣的矩形應該給你你需要的位置左,右,上,下。此外,您可以獲取BitmapData並在不安全的上下文中對其進行掃描(通過操作指向原始位圖數據的指針),這將比使用GetPixel()更快。 – 2009-07-23 18:47:58