Search
Advertisement #3
http://www.salestraining.co.in
Salestraining offer sales training courses and sales training programs throughout India.
Account Login
| Image Formatting in C# (GDI+) |
|
|
|
| Blog - Review |
|
Working with the GDI+ framework is not (in some cases) as trivial as you would think. It may be easy to create a new Bitmap object and draw some primitive shapes and text to it, but when you start trying to use the GDI+ library for changing the format of an Image it gets a little more tricky. Here I am going to discuss some of the ins and outs of working with GDI+ for image formatting, such as creating/saving images and changing image.s formats. My initial goal was to create a method that could accept an Image object as input and output a TIFF formatted byte array. I.m going to start out by describing how you go about creating a multi-framed tiff image in some basic steps:
One of the key concepts to note here (that isn.t completely obvious) is that as you add new frames to the image with SaveAdd(), it is adding on to the stream that the image was originally saved to. In other words, you tell the Image object where to save the image data to, and as you add more frames to the image, the Image object appends the saved data. If you were to use the Image.Save(string, ImageCodecInfo, EncoderParameters) method instead of the Stream version, you could watch the size of the file change in between each call to SaveAdd(). Note: If you rely on Visual Studio.s intellisense like I do, and you type .Encoder.. and expect to see a list of the enumeration values but don.t, it is probably because you have a .using System.Text;. in your class file. The System.Text namespace has a class named .Encoder. as well that conflicts with the one in System.Drawing.Imaging; so when your intellisense pops up for the Encoder class it is displaying the members of the System.Text.Encoder class, not the System.Drawing.Imaging.Encoder class.
You might have noticed that in the example above I used the .Save(string, .) method instead of .Save(Stream, .). Originally I had intended for the createMultiFrameTiff() method to return an Image object that could be used right away. After adding all the frames and Flushing the image the image still only contains a single frame (at least that.s what the GetFrameCount() method returns). It is only after you save the Image to a file system and load the image back into a completely new Image object by using Image.FromFile() that multiple frames are returned by GetFrameCount(). GDI+ is very odd in this respect because no matter what, if you don.t save the image to an actual file and load the file into the Image object, the multiple frames are not registered and thus not returned in the calls to GetFrameCount() or SelectActiveFrame(). Even saving the image to a stream, reading the bytes from the stream, loading the bytes into a new stream and calling Image.FromStream with the new stream does not really work. With that approach, I was able to the correct count of frames from GetFrameCount(), but as soon as you call SelectActiveFrame() a .Generic. GDI+ exception is thrown. In fact, any time I have loaded a multi-frame TIFF using Image.FromStream and call SelectActiveFrame() I receive exceptions from GDI+. However, even though GetFrameCount() and SelectActiveFrame() don.t work when building a multi-frame TIFF image in memory doesn.t work properly, the data in the stream is still a valid multi-frame TIFF. If you save the bytes from the stream that is used to build the multi-frame TIFF to a file and then call Image.FromFile() you will find that the image has all the frames that you added to it and can select each individual frame successfully. Note: The Windows Picture Viewer (preview) application supports multiple framed TIFF images. This is one of the only popular image viewing programs that I have found that supports multi-frame TIFF images. Photoshop doesn.t, Paint.Net doesn.t, Microsoft Paint DEFINATELY doesn.t. Compression Specifying the compression of the image is very easy. All you have to do is add an additional parameter to the EncoderParameters object. Instead of creating the EncoderParameters object with one (1) parameter, create it with two (2) and set the appropriate EncoderValue. For example:" Download Example Here is a link to download the (working) example code for creating (and displaying) a multi-frame TIFF image. |
| Last Updated on Tuesday, 26 May 2009 14:02 |






Comments
I moved to use Image.FromFile with a temp file name as suggested here. However following that I used Image.FromStream, and had the same success. Therefore it would seem that my original method of loading my byte array to a stream, then into a Bitmap did not load the additional tiff information that Image.FromStream does. Quote
What worked for me is to call File.WriteAllBytes(f ilename, memorystream.getbuffer());
Then read that file in. Quote