In the course of writing the program for the analysis of diffraction patterns, a dead end arose. enter image description here It does not work quickly and correctly with the pixels of the photo.

While there was a prototype, GetPixel suited, but now ... I tried 4 ways. All return an array, but not he is not a bit like.

The last and most sane result is through LockPits (at least the size of the array is correct), but the values ​​are not the same (in the center 255 there should be a lot of black and white), but in the end it doesn’t enter one hundred square meters.

This is a function to convert.

public byte[] imageToByteArray(Bitmap bmp) { var pxf = System.Drawing.Imaging.PixelFormat.Format24bppRgb; // ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ Π΄Π°Π½Π½Ρ‹Π΅ ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΊΠΈ. var rect = new System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height); //Π‘Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅ΠΌ Π½Π°Π±ΠΎΡ€ Π΄Π°Π½Π½Ρ‹Ρ… изобраТСния Π² памяти BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadWrite, pxf); // ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ адрСс ΠΏΠ΅Ρ€Π²ΠΎΠΉ Π»ΠΈΠ½ΠΈΠΈ. IntPtr ptr = bmpData.Scan0; // Π—Π°Π΄Π°Ρ‘ΠΌ массив ΠΈΠ· Byte ΠΈ ΠΏΠΎΠΌΠ΅Ρ‰Π°Π΅ΠΌ Π² Π½Π΅Π³ΠΎ Π½Π°Π΄ΠΎΡ€ Π΄Π°Π½Π½Ρ‹Ρ…. // int numBytes = bmp.Width * bmp.Height * 3; //На 3 ΡƒΠΌΠ½ΠΎΠΆΠ°Π΅ΠΌ - ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ RGB Ρ†Π²Π΅Ρ‚ кодируСтся 3-мя Π±Π°ΠΉΡ‚Π°ΠΌΠΈ //Π›ΠΈΠ±ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ вмСсто Width - Stride int numBytes = bmpData.Stride * bmp.Height; int widthBytes = bmpData.Stride; byte[] rgbValues = new byte[numBytes]; // ΠšΠΎΠΏΠΈΡ€ΡƒΠ΅ΠΌ значСния Π² массив. Marshal.Copy(ptr, rgbValues, 0, numBytes); return rgbValues; } 

This is the main code.

  ImageBrush ib = new ImageBrush(); var current_bimage = new BitmapImage(new Uri("(gray).jpg", UriKind.RelativeOrAbsolute)); int widthX=current_bimage.PixelWidth; int heightY=current_bimage.PixelHeight; byte[] bData = imageToByteArray(new Bitmap("(gray).jpg")); //System.Drawing.Image asdfa = new Bitmap("./(gray).jpg"); var count_bData=bData.Count(); //List<MyPoint> points = new List<MyPoint>(); byte max=255; Stack<int> X = new Stack<int>(); Stack<int> Y = new Stack<int>(); int ara; int c_pixels = 0; int y; int x; int i = -3; for (y = 0; y < heightY; y++) { x = 0; for (x = 0; x < widthX; x=x+1) { var mid = ( bData[y * x]); // var mid = (30 * bData[y * x] + 59 * bData[y * x + 1] + 11 * bData[y * x + 2]) / 100; //Console.WriteLine(y + " " + x + " " + mid + bData[y * x] + bData[y * x + 1] + bData[y * x + 2]); if (mid == max) { Y.Push(y); X.Push(x); c_pixels++; } } } var midX = X.Sum() / c_pixels; var midY = Y.Sum() / c_pixels; 
  • Are you sure you guessed the format? - VladD
  • What is bmp.PixelFormat ? - VladD
  • one
    var mid = ( bData[y * x]); - wrong. Must be var midR = bData[y * Stride + x * 3]; var midG = bData[y * Stride + x * 3 + 1]; var midB = bData[y * Stride + x * 3 + 2]; var midR = bData[y * Stride + x * 3]; var midG = bData[y * Stride + x * 3 + 1]; var midB = bData[y * Stride + x * 3 + 2]; - VladD
  • @VladD No, so I tried all the suggested formats. Earned, thank you very much. Do I understand correctly that Stride sets the step through which the pixel values ​​are found? - Arantler
  • one
    Stride specifies the size of a single line in bytes . If it worked, I will write in response. - VladD

1 answer 1

I think that the error in the code

 var mid = ( bData[y * x]); 

It should be like this:

 var midR = bData[y * Stride + x * 3]; var midG = bData[y * Stride + x * 3 + 1]; var midB = bData[y * Stride + x * 3 + 2]; 

Explanation: Stride specifies the size of the string in bytes, therefore y * Stride is the starting byte number for the y -th string. Each pixel occupies 3 bytes in Format24bppRgb format, so we need a byte in the line with an offset of x * 3 , and two following it.