Manipulate 32-bit image pixels using a class with simple pixel get and set methods in C#

The example Manipulate image pixels very quickly using LockBits wrapped in a class in C# shows how to build a class that lets you access an image's pixels very quickly but to do so you need to manipulate the pixels' red, green, and blue components in a large byte array. That means you need to calculate offsets into that array, which can be confusing.

This example makes two changes. First, it uses a 32-bit bitmap instead of a 24-bit bitmap so you can manipulate each pixel's alpha value (opacity) in addition to its red, green, and blue components. Second, it provides GetPixel, SetPixel, GetRed, SetRed, GetGreen, SetGreen, GetBlue, SetBlue, GetAlpha, and SetAlpha methods to make working with pixels easier.

When you click the Quarter button, the program uses those methods to modify an image so each quarter displays a different effect and so each is partially transparent. It then draws the image over a white ellipse so you can see the ellipse showing through.

public class Bitmap32
{
// Provide public access to the picture's byte data.
public byte[] ImageBytes;
public int RowSizeBytes;
public const int PixelDataSize = 32;

// A reference to the Bitmap.
private Bitmap m_Bitmap;

// Save a reference to the bitmap.
public Bitmap32(Bitmap bm)
{
m_Bitmap = bm;
}

// Bitmap data.
private BitmapData m_BitmapData;

// Return the image's dimensions.
public int Width
{
get
{
return m_Bitmap.Width;
}
}
public int Height
{
get
{
return m_Bitmap.Height;
}
}

// Provide easy access to the color values.
public void GetPixel(int x, int y, out byte red, out byte green, out byte blue, out byte alpha)
{
int i = y * m_BitmapData.Stride + x * 4;
blue = ImageBytes[i++];
green = ImageBytes[i++];
red = ImageBytes[i++];
alpha = ImageBytes[i];
}
public void SetPixel(int x, int y, byte red, byte green, byte blue, byte alpha)
{
int i = y * m_BitmapData.Stride + x * 4;
ImageBytes[i++] = blue;
ImageBytes[i++] = green;
ImageBytes[i++] = red;
ImageBytes[i] = alpha;
}
public byte GetBlue(int x, int y)
{
int i = y * m_BitmapData.Stride + x * 4;
return ImageBytes[i];
}
public void SetBlue(int x, int y, byte blue)
{
int i = y * m_BitmapData.Stride + x * 4;
ImageBytes[i] = blue;
}
public byte GetGreen(int x, int y)
{
int i = y * m_BitmapData.Stride + x * 4;
return ImageBytes[i + 1];
}
public void SetGreen(int x, int y, byte green)
{
int i = y * m_BitmapData.Stride + x * 4;
ImageBytes[i + 1] = green;
}
public byte GetRed(int x, int y)
{
int i = y * m_BitmapData.Stride + x * 4;
return ImageBytes[i + 2];
}
public void SetRed(int x, int y, byte red)
{
int i = y * m_BitmapData.Stride + x * 4;
ImageBytes[i + 2] = red;
}
public byte GetAlpha(int x, int y)
{
int i = y * m_BitmapData.Stride + x * 4;
return ImageBytes[i + 3];
}
public void SetAlpha(int x, int y, byte alpha)
{
int i = y * m_BitmapData.Stride + x * 4;
ImageBytes[i + 3] = alpha;
}

// Lock the bitmap's data.
public void LockBitmap()
{
// Lock the bitmap data.
Rectangle bounds = new Rectangle(
0, 0, m_Bitmap.Width, m_Bitmap.Height);
m_BitmapData = m_Bitmap.LockBits(bounds,
ImageLockMode.ReadWrite,
PixelFormat.Format32bppArgb);
RowSizeBytes = m_BitmapData.Stride;

// Allocate room for the data.
int total_size = m_BitmapData.Stride * m_BitmapData.Height;
ImageBytes = new byte[total_size];

// Copy the data into the ImageBytes array.
Marshal.Copy(m_BitmapData.Scan0, ImageBytes, 0, total_size);
}

// Copy the data back into the Bitmap
// and release resources.
public void UnlockBitmap()
{
// Copy the data back into the bitmap.
int total_size = m_BitmapData.Stride * m_BitmapData.Height;
Marshal.Copy(ImageBytes, 0, m_BitmapData.Scan0, total_size);

// Unlock the bitmap.
m_Bitmap.UnlockBits(m_BitmapData);

// Release resources.
ImageBytes = null;
m_BitmapData = null;
}
}

   

 

What did you think of this article?




Trackbacks
  • No trackbacks exist for this post.
Comments
  • No comments exist for this post.
Leave a comment

Submitted comments are subject to moderation before being displayed.

 Name

 Email (will not be published)

 Website

Your comment is 0 characters limited to 3000 characters.