Example 4: Image Processing in Windows Presentation Foundation (.NET Framework 3.0)
Many image processing researchers which they develop on .NET/C# they still stuck in
GDI+. That means, they still using the unsafe bracket and by pointers they get the
image information. This has changed since the introduction of the Windows
Presentation Foundation (WPF) for .NET Framework 3.0 and beyond. In this blog post,
we will discuss how to open and process an image using the WPF tools. Let's consider
that the image.png is a 32bits/pixel color image. To access the image pixels:
PngBitmapDecoder myImage
= new PngBitmapDecoder(new Uri("image.png"), BitmapCreateOptions.DelayCreation,BitmapCacheOption.OnLoad);byte[]
myImageBytes = new byte [myImage.Frames[0].PixelWidth * 4 * myImage.Frames[0].PixelHeight];
myImage.Frames[0].CopyPixels(myImageBytes, myImage.Frames[0].PixelWidth * 4, 0);
At first line, a image object is created by using the pngbitmapdecoder class. The
myImage.Frames collection holds the image information. In this example, an image is
opened so the collection is equal to 1 and the picture is accessed by the
myImage.Frames[0].
Then a byte array is created which it will hold the image pixels information. The
CopyPixels function of the Frames[0] is used to get the pixels of the opened image. In
this particular example because the image format is Bgra32, the array byte size is equal
to 4*Width*Height. In general, the ordering of bytes in the bitmap corresponds to the
ordering of the letters B, G, R, and A in the property name. So in Bgra32 the order is
Blue, Green, Red and Alpha. Generally, the image format for the image is accessed by
myImage.Frames[0].Format and the palette (if the image is using one) by
myImage.Frames[0].Palette.
To manipulate the image pixels in order to create a greyscale image:
int Width = myImage.Frames[0].PixelWidth;
int Height = myImage.Frames[0].PixelHeight;
for (int x = 0; x < Width; x++)
{
for (int y = 0; y < Height; y++)
{
int r = myImageBytes[4 * x + y * (4 * Width) + 2];
int g = myImageBytes[4 * x + y * (4 * Width) + 1];
int b = myImageBytes[4 * x + y * (4 * Width) + 0];
int greyvalue = (int)(0.3 * r + 0.59 * g + 0.11 * b);
myImageBytes[4 * x + y * (4 * Width) + 2] = (byte)greyvalue;
myImageBytes[4 * x + y * (4 * Width) + 1] = (byte)greyvalue;
myImageBytes[4 * x + y * (4 * Width) + 0] = (byte)greyvalue;
}
}
Finally, to create a new image object from the byte array and save it:
BitmapSource myNewImage = BitmapSource.Create(Width, Height, 96, 96, PixelFormats.Bgra32, null, myImageBytes, 4 *
Width);BmpBitmapEncoder enc = new
BmpBitmapEncoder();
enc.Frames.Add(BitmapFrame.Create(myNewImage));FileStream fs = newFileStream("newimage.png", FileMode.Create);
enc.Save(fs);fs.Close();