I have a class that creates a matrix of Color values by reading a Bitmap. The class directly reads each byte in the pixels inside an unsafe block using the pointer to the image. The purpose of the class is to read the pixel values into memory where I can run filters on them before saving the image as a new file.
I can recreate the image using GDI+‘s setPixel() method, however it is too slow for my needs.
I am attempting to save a new image file using the following function:
public void saveImageFromPixels()
{
this.newBitmap = new Bitmap(srcBitmap.Width, srcBitmap.Height);
BitmapData imgData = newBitmap.LockBits(new Rectangle(0, 0, newBitmap.Width, newBitmap.Height),
ImageLockMode.ReadWrite,
PixelFormat.Format24bppRgb);
int stride = imgData.Stride;
System.IntPtr Scan0 = imgData.Scan0;
unsafe
{
byte* p = (byte*)(void*)Scan0;
int nOffset = stride - newBitmap.Width * 3;
for (int x = 0; x < newBitmap.Height; ++x)
{
for (int y = 0; y < newBitmap.Width; ++y)
{
p[0] = (byte)(255 - matrix[y][x].B);
p[1] = (byte)(255 - matrix[y][x].G);
p[2] = (byte)(255 - matrix[y][x].R);
p += 3;
}
p += nOffset;
}
}
this.newBitmap.Save(@"C:\images\1-d.jpg");
}
However the result is an empty image (with the proper dimensions). The code that directly accesses the pixels and saves the value as a Color works fine, it is just saving the image I am having problems with.
The following code defines srcBitmap and newBitmap
private Bitmap srcBitmap;
private Bitmap newBitmap;
private List<List<Color>> matrix;
public PixelMatrix(string path)
{
this.srcBitmap = new Bitmap(path);
this.matrix = new List<List<Color>>(srcBitmap.Width);
for (int x = 0; x < srcBitmap.Width; x++)
{
this.matrix.Add(new List<Color>(srcBitmap.Height));
}
}
You need to
UnlockBits().