Friday, February 03, 2006

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 3000x2000 image into a 300x200 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)
        {
            IBitmapImage imageBitmap;
            ImageInfo ii;
            IImage image;

            ImagingFactory factory = new ImagingFactoryClass();
            factory.CreateImageFromStream(new StreamOnFile(stream), out image);
            image.GetImageInfo(out ii);
            factory.CreateBitmapFromImage(image, (uint)size.Width, (uint)size.Height, 
          ii.PixelFormat, InterpolationHint.InterpolationHintDefault, out imageBitmap);
            return 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

TBD

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 = new ImagingFactoryClass();
IImage
img;
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, h
eight);
img.Draw(hDC, rc,
null
);
g.ReleaseHdc(hDC);

The above code will transparently draw rgba8.png over the specified bitmap.

2/3/2006 5:13:30 PM (Pacific Standard Time, UTC-08:00)  #    Comments [7]  | 
2/1/2007 10:35:52 PM (Pacific Standard Time, UTC-08:00)
I'm a Chinese boy, many many thanks for your article, the big image now can be showed in my program, but how to draw parts of the image via IImage.Draw? Thanks again!
3/30/2007 7:55:51 AM (Pacific Daylight Time, UTC-07:00)
One Question....about the transparent pngs, Whats the code in VB.NET?
--------------------------------------------------
Dim factory As OpenNETCF.Drawing.Imaging.ImagingFactory = New OpenNETCF.Drawing.Imaging.ImagingFactoryClass()

Dim img As OpenNETCF.Drawing.Imaging.IImage
factory.CreateImageFromFile(API.AppPath & "bin\overlay.png", img)

Dim imageBackground As Bitmap = New Bitmap("MyImage.bmp")

Dim g As Graphics = Graphics.FromImage(imageBackground)

Dim hDC As IntPtr = g.GetHdc()
Dim rc As OpenNETCF.Drawing.Imaging.RECT = OpenNETCF.Drawing.Imaging.RECT.FromXYWH(20, 20, Image1.Width, Image1.Height)

img.Draw(hDC, rc, Nothing)
g.ReleaseHdc(hDC)
-------------------------
Doesn't display anything
5/8/2007 12:04:25 AM (Pacific Daylight Time, UTC-07:00)
Hi,
Thank you very much for the code lines that you providing (I'm not talking about only these from this page :) )!

I'm newbie I can't make working the code for transparent png file... I put your code on a function that is called when a button is pressed and after that in override OnPaint and doesn't display anything... :( Please help me telling where I need to insert that lines.

Regards
6/21/2007 2:01:30 PM (Pacific Daylight Time, UTC-07:00)
Same here, transparancy code just shows a blank page. Anyone has got this to work?
10/16/2007 6:28:21 AM (Pacific Daylight Time, UTC-07:00)
Hello everybody! I need a little piece of advice: I am considering buying a notebook and the macBook or macBook Pro look very appealing; however I would probably put a Linux distribution on it so is it worth me spending on a mac book when I'm not going to use the OS X?
3/5/2008 9:46:30 PM (Pacific Standard Time, UTC-08:00)
yup, i tried to play with that code and at the moment i am also getting nothing, seems like maybe the bmp needs to be created from scratch with argb?
zxed
4/8/2008 9:06:11 AM (Pacific Daylight Time, UTC-07:00)
Hi! I tried to load a large image in the PDA using your code but it throws a COMexception when CreateBitmapFromImage is called...any clues?
if you want to see the code just ask for it :D
Name
E-mail
Home page

Comment (HTML not allowed)  

Enter the code shown (prevents robots):