0

Currently I have this, I am searching for the RGB value (208, 94, 94) and if there is a match, it will tell my DX device to draw on the screen and aswell log it in the console.

Well, I am not exactly sure how to get the exact X,Y coordinates of the pixel. The Y is fine and not the problem, but the X is always off and a high value. How should I get the X, Y? Is there a formula or is my code wrong? Is there a way to use GetPixel inside LockBits with it being fast?

For example it prints:

x: 3772 y: 187 when the actual value is: 944, 187

x: 3888 y: 212 when the actual value is: 973, 212

x: 3788 y: 224 when the actual value is: 948, 224

unsafe
{
    using (System.Drawing.Bitmap bmp = new System.Drawing.Bitmap("FileName.png"))
    {

        BitmapData bitmapData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, bmp.PixelFormat);
        int bytesPerPixel = System.Drawing.Bitmap.GetPixelFormatSize(bmp.PixelFormat) / 8;
        int heightInPixels = bitmapData.Height;
        int widthInBytes = bitmapData.Width * bytesPerPixel;
        byte* ptrFirstPixel = (byte*)bitmapData.Scan0;

        for (int y = 0; y < heightInPixels; y++)
        {
            byte* currentLine = ptrFirstPixel + (y * bitmapData.Stride);


            for (int x = 0; x < widthInBytes; x = x + bytesPerPixel)
            {
                int Blue = currentLine[x];
                int Green = currentLine[x + 1];
                int Red = currentLine[x + 2];

                if (Red == 208 & Green == 94 & Blue == 94)
                {
                   // Device.DrawText("Unit", TextFont, new RawRectangleF(x, y, float.MaxValue, float.MaxValue), UnitTextBrush);

                    Console.WriteLine($"x: {x} y: {y}");

                    break;
                }
            }
        }

        bmp.UnlockBits(bitmapData);
    }
}
Rand Random
  • 7,300
  • 10
  • 40
  • 88
  • You don't see the correlation of the actual value and the observed value? (Hint: I'ts `actual = observed / 4 + 1`). – Sani Huttunen Oct 15 '18 at 17:52
  • _Is there a way to use GetPixel inside LockBits with it being fast?_ lool, no. Just use the x,y coordinates and understand that x points into an array of BGRA channels; also understand the stride offset.. – TaW Oct 15 '18 at 17:58
  • 1
    @hadesxo, The `actual = observed / 4 + 1` was just a hint. To make the correct calculation you'd want to use `bytesPerPixel` instead of 4. – Sani Huttunen Oct 15 '18 at 18:00
  • If you want `x` to mean the column index then you should compute `byte *pixel = ptrFirstPixel + (y * bitmapData.Stride) + x * bytesPerPixel.` And let the loop go naturally from 0 to bitmapData.Width. But your computation of bytesPerPixel looks wrong. Why divide by 8? You should just lock the bits in a canonical format like Format32bppArgb and hard code the bytesPerPixel to be 4. – Wyck Oct 15 '18 at 18:01
  • To be more concise, on my comment about pixel format: coding for the flexibility of locking the bitmap in the format of `bmp.PixelFormat`, but then hard coding the loop to read channels as 8-bits-per-channel in the BGR order, really seems naively optimistic. You should specify locking the image in the canonical format of Format32bppRgb since that's how the code that follows accesses the memory. – Wyck Oct 15 '18 at 18:07

0 Answers0