BitmapData to Change Pixel Format in GDI+


This article has been excerpted from book "Graphics Programming with GDI+".

In the previous section we discussed how to set the pixel format of a bitmap by reading pixels one by one. You can also set the pixel format by using the BitmapData class and its members.

The BitmapData object specifies the attributes of a bitmap, including size, pixel format, starting address of the pixel data in memory, and length of each scan line (stride). These properties are described in Table 8.3. All of the properties have both get and set types.

Now let's set the color of pixels in a bitmap by using LockBits and UnlockBits. This approach is faster than using the SetPixel method. Listing 8.2 uses LockBits and UnlockBits to set a bitmap pixel format. First we create an Image object from a file, followed by a Bitmap object from the Image object. Then we call LockBits, which returns as BitmapData object. Next we call PixelFormat to set the pixel format. You can use any of the PixelFormat enumeration values. Finally we call UnlockBits to unlock the locked bits. Notice that the lockedRect rectangle in the LockBits method is the size of the bitmap.

LISTING: 8.2: Using LockBits and UnlockBits to set the grayscale of a bitmap

        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            Image img = Image.FromFile("roses.jpg");
            Bitmap curImage = new Rectangle(0, 0, curImage.Width, curImage.Height);
            Rectangle lockedRect = new Rectangle(0, 0, curImage.Width, curImage.Height);
            BitmapData bmpData = curImage.LockBits(lockedRect, ImageLockMode.ReadWrite,
            PixelFormat.Format24bppRgb);

            // Set the format of BitmapData pixels
            bmpData.PixelFormat = PixelFormat.Max;

            // Unlock the locked bits
            curImage.UnlockBits(bmpData);

            // Draw image with new pixel format
            e.Graphics.DrawImage(curImage, 0, 0,
            curImage.Width, curImage.Height);
        }

TABLE 8.3: BitmapData properties

Property

Description

Height

Represents the pixel height.

PixelFormat

Represents the format of the pixels using the PixelFormat enumeration.

Scan0

Represents the address of the first pixel data in the bitmap.

Stride

Represents stride (also called scan width).

Width

Represents the pixel width.

Figure 8.1 shows the output from listing 8.2. The entire bitmap is grayscale.

If a bitmap is huge and we want to change the format of only few pixels, LockBits and UnlockBits really help. Using these methods, we can lock and render only the part of a bitmap we want to work on instead of rendering the entire bitmap. Suppose we want to change the pixel format of only the section of the bitmap starting at point (50, 50) and ending at point (200, 200). We simply change the rectangle passed to LockBits.

Listing 8.3 locks only that portion of the image specified by a rectangle.

Figure-8.1.jpg

FIGURE 8.1: Using BitmapData to set grayscale

LISTING 8.3: Changing the pixel format of a partial bitmap

        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            Image img = Image.FromFile("Roses.jpg");
            Bitmap curImage =
            new Bitmap(img, new Size(img.Width, img.Height));

            // Call LockBits, which returns a BitmapData object
            Rectangle lockedRect = new Rectangle(50, 50, 200, 200);

            /* Rectangle lockedRect =
             new Rectangle (0, 0 curImage.width, curImage.Height);
             */
            BitmapData bmpData = curImage.LockBits(lockedRect,
            ImageLockMode.ReadWrite,
            PixelFormat.Format24bppRgb);

            // Set the format of BitmapData pixels
             bmpData.PixelFormat = PixelFormat.Max;

            // Unlock the locked bits
             curImage.UnlockBits(bmpData);

            // Draw image with new pixel format
             e.Graphics.DrawImage(curImage, 0, 0,
            curImage.Width, curImage.Height);
        }

Figure 8.2 shows the output from Listing 8.3. You may not see any difference between this illustration and Figure 8.1, but if you run the sample code yourself, you will notice that the color of only a small rectangle in the image is changed.

Figure 8.2.jpg

FIGURE 8.2: Changing the pixel format of a partial bitmap

Conclusion

Hope the article would have helped you in understanding BitmapData to Change Pixel Format in GDI+. Read other articles on GDI+ on the website.

bookGDI.jpg
This book teaches .NET developers how to work with GDI+ as they develop applications that include graphics, or that interact with monitors or printers. It begins by explaining the difference between GDI and GDI+, and covering the basic concepts of graphics programming in Windows.