NOTE: This entry is originally from Feb 3, 2006 and was recovered from the Internet Wayback Machine on May 27, 2014 due to demand for the content. Some links, etc may no longer be valid.
As promised, here are some details on the OpenNETCF.Drawing.Imaging namespace. I’m going to demonstrate how to accomplish several tasks listed in the previous post as not supported by the CF Bitmap class.
0. Preface. helper classes
In the wrapper we introduce 2 helper classes – StreamOnFile and ImageUtils. The latter is simply a collection of high-level image proverssing methods. The former is an IStream implemented over .NET Stream (including FileStream). The implementation is not complete, but sufficient for the Imaging API methods that expect an IStream parameter.
1. Thumbnails, loading parts of the large image
Loading an image in Imaging API is achieved via calls to decoders – COM objects implementing IImageDecoder interface. The basic imaging interface IImage uses decoders to load image data. Most of the decoders support loading partial image, dicarding the unnecessary data. E.g. if you need to load a 3000×2000 image into a 300×200 PictureBox control, it is obvious that you don’t need all 6MP of data taking a whopping 18 MB of RAM (24bpp). Moreover, most devices will simply throw an OutOfMemoryException fi you try something like this. Decoder can be instructed to load an image of the required size so that it will skip over those pixels that don’t make it (or factor them into interpolation process to scale the image more smoothly). Here is how we achieve it.
static public IBitmapImage CreateThumbnail(Stream stream, Size size)
ImagingFactory factory = new ImagingFactoryClass();
factory.CreateImageFromStream(new StreamOnFile(stream), out image);
factory.CreateBitmapFromImage(image, (uint)size.Width, (uint)size.Height,
ii.PixelFormat, InterpolationHint.InterpolationHintDefault, out imageBitmap);
After we got IBitmapImage object, we can convert it to the .NET Bitmap:
Bitmap bm = ImageUtils.IBitmapImageToBitmap(imageBitmap);
2. Image transformation (flip, rotate, gamma/brightness/contrast controls)
Imaging library offers a limited set of the image operations exposed via interface IBasicBitmapOps. These are also wrapped in the ImageUtils class so that you get the following methods:
public Bitmap RotateFlip(Bitmap bitmap, RotateFlipType type)
public Bitmap Rotate(Bitmap bitmap, float angle)
public Bitmap Flip(Bitmap bitmap, bool flipX, bool flipY)
Of course you are welcome to use the IBasicBitmapOps directly.
3. Image tags
4. Transparency and alpha blending
If you have a PNG image with alpha channel information and you load it into a Bitmap object, the transparency is immediately lost. Not so, if using IImage class.
ImagingFactory factory = newImagingFactoryClass();
factory.CreateImageFromFile(“rgba8.png”, out img);
Bitmap imageBackground = new Bitmap(“MyImage.bmp“);
Graphics g = Graphics.FromImage(imageBackground);
IntPtr hDC = g.GetHdc();
RECT rc = RECT.FromXYWH(200, 200, width, height);
img.Draw(hDC, rc, null);
The above code will transparently draw rgba8.png over the specified bitmap.