How to get and set pixels from gif image faster using lockbits ?

Ben Shmil 41 Reputation points
2022-11-26T10:55:28.507+00:00

This is what i'm using now but the inner loop with the c variable takes a lot of time because there are over 290,000 pixels.

usage

public UserControlTester()  
        {  
            InitializeComponent();  
  
            GetSetPixelsRandom();  
        }  

and

private void GetSetPixelsRandom()  
        {  
            Bitmap img = new Bitmap(@"d:\\downloaded images\\test.gif");  
            for (int i = 0; i < img.Width; i++)  
            {  
                for (int j = 0; j < img.Height; j++)  
                {  
                    Color pixel = img.GetPixel(i, j);  
                    pixels.Add(pixel);  
                }  
            }  
  
            Bitmap img1 = new Bitmap(512,512);  
  
            for (int i = 0; i < img1.Width; i++)  
            {  
                for (int j = 0; j < img1.Height; j++)  
                {  
                    for (int c = 0; c < pixels.Count; c++)  
                    {  
                        img1.SetPixel(i, j, pixels[c]);  
                    }  
                }  
            }  
  
            img1.Save(@"d:\\downloaded images\\test3.gif");  
        }  

my general goal is to take image read the image pixels to list then mix the list and then to set the pixels back to the image.
so each time the image pixels will be in random locations. so each time the new image will be with the same pixels and colors of the original image but the pixels will be in random positions so the new image will never be the same as the original.

but first i don't know how to use the lockbits.

I thought to use this method :

public unsafe Image ThresholdUA(Bitmap _image)  
        {  
            Bitmap b = new Bitmap(_image);//note this has several overloads, including a path to an image  
  
            BitmapData bData = b.LockBits(new Rectangle(0, 0, _image.Width, _image.Height), ImageLockMode.ReadWrite, b.PixelFormat);  
  
            byte bitsPerPixel = GetBitsPerPixel(bData.PixelFormat);  
  
            /*This time we convert the IntPtr to a ptr*/  
            byte* scan0 = (byte*)bData.Scan0.ToPointer();  
  
            for (int i = 0; i < bData.Height; ++i)  
            {  
                for (int j = 0; j < bData.Width; ++j)  
                {  
                    byte* data = scan0 + i * bData.Stride + j * bitsPerPixel / 8;  
  
                    //data is a pointer to the first byte of the 3-byte color data  
                    //data[0] = blueComponent;  
                    //data[1] = greenComponent;  
                    //data[2] = redComponent;  
                }  
            }  
  
            b.UnlockBits(bData);  
  
            return b;  
        }  

but GetBitsPerPixel is not exist i'm not sure what should be in this method if i create it.

and how to use the whole ThresholdUA method ?

Developer technologies | Windows Forms
Developer technologies | C#
0 comments No comments
{count} votes

Accepted answer
  1. Castorix31 90,686 Reputation points
    2022-11-26T11:18:28.603+00:00

    See the MSDN sample with a byte array : Bitmap.LockBits
    or a sample with a loop I had posted in this thread : Pixel manipulation written in csharp needs more than an automatic conversion. I need some help to convert.


0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.