Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>The Bitmap class contains a GetPixel method that returns the Color of a pixel in the bitmap, given its X and Y coordinates. One technique might be to walk the rows and columns of data to determine the lowest X and Y coordinates at which a non-white pixel exists. This technique is adequate if the images are small and/or performance is not a prime consideration since calling GetPixel is rather slow.</p> <p>Another approach would be to get the Bitmap image data into a byte[] and then walk the bytes in the array to determine the location of the non-white pixels. This approach requires some knowledge of the way bytes are laid out for a given bitmap type (e.g. 32 bit, 24 bit, 1 bit, etc.).</p> <p>To get the bytes for a bitmap, you call the LockBits method on the bitmap to lock a region of the bitmap and obtain a BitmapData object. You then use the Stride and Height properties of the BitmapData object to determine the size of the byte array needed to contain the bitmap.</p> <p>I whipped up and tested the following method, which seems to work speedily on a couple test images I created to detect the location of an ellipse.</p> <pre><code>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 &lt; height; y++) { sourceIndex = y * sourceData.Stride; // Iterate pixels for (int x = 0; x &lt; 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 &lt; threshold) { minX = Math.Min(minX, x); minY = Math.Min(minY, y); } sourceIndex += 4; } } return new Point(minX, minY); } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload