How to process pixel by pixel using WinAPI in FAST WAY?

So, I am making a simple GUI image processing program, C #. For example, I want to change the colors of images in the HSV color model by converting each pixel from RGB and vice versa.

My program loads an image of the user's choice and displays it on one of the form panels using the Graphics context. Then the user can do something with this image by moving the scroll bars, clicking buttons, selecting an image area, etc. When he does, I need to change all the pixel pixels in real time. So, I am writing something like:

for (int x = 0; x < imageWidth; x++) for (int y = 0; y < imageHeight; y++) Color c = g.GetPixel(x, y); c = some_process_color_function_depending_on_user_controls(c); g.SetPixel(x, y) 

And even if I work with graphics in memory (not on the screen), the GetPixel and SetPixel functions work VERY SLOW (since my program runs so slowly, I profiled it and explained that these two functions slow down my programs no more) . Thus, I cannot process large snapshots in a few seconds when the user moves the slider or checking the checkbox.

Please, help! What can I do to make my program fast? I agree to use other third-party libraries for graphics or change the programming language!

+6
source share
1 answer

The functions Yep, Get / SetPixel are very slow. Use Bitmap.LockBits () / UnlockBits () instead . It returns raw bit data so you can manipulate.

From the msdn link:

 private void LockUnlockBitsExample(PaintEventArgs e) { // Create a new bitmap. Bitmap bmp = new Bitmap("c:\\fakePhoto.jpg"); // Lock the bitmap bits. Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height); System.Drawing.Imaging.BitmapData bmpData = bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, bmp.PixelFormat); // Get the address of the first line. IntPtr ptr = bmpData.Scan0; // Declare an array to hold the bytes of the bitmap. // This code is specific to a bitmap with 24 bits per pixels. int bytes = bmp.Width * bmp.Height * 3; byte[] rgbValues = new byte[bytes]; // Copy the RGB values into the array. System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes); // Set every red value to 255. for (int counter = 2; counter < rgbValues.Length; counter+=3) rgbValues[counter] = 255; // Copy the RGB values back to the bitmap System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes); // Unlock the bits. bmp.UnlockBits(bmpData); // Draw the modified image. e.Graphics.DrawImage(bmp, 0, 150); } 
+7
source

Source: https://habr.com/ru/post/925613/


All Articles