Files is the most common storage for images. All the imaging components can load and save images to files of various formats. Let's examine how to work with files using Graphics Mill for .NET.
The simplest way to load or save image from or to a file is to use Load or Save method of the Bitmap class. Being easy-to-use and convenient they provide not all the features of Graphics Mill for .NET to deal with files. E.g. these methods does not provide multiple frames support, working with EXIF and IPTC metadata, asynchronous work, etc.
More advanced method is to use classes from Aurigma.GraphicsMill.Codecs namespace. They enables you to use all the power of Graphics Mill for .NET when working with files.
Let's examine it more detailed.
To load image from file using the Bitmap class, just pass the desired filename into Load method.
Dim bitmap As New Aurigma.GraphicsMill.Bitmap bitmap.Load("c:\mountain.jpg")
Aurigma.GraphicsMill.Bitmap bitmap = new Aurigma.GraphicsMill.Bitmap(); bitmap.Load(@"c:\mountain.jpg");
Alternatively you can use a constructor of the Bitmap class.
Dim bitmap As New Aurigma.GraphicsMill.Bitmap("c:\mountain.jpg")
Aurigma.GraphicsMill.Bitmap bitmap = new Aurigma.GraphicsMill.Bitmap(@"c:\mountain.jpg");
Saving to file is also easy. Pass target filename into Save method of the Bitmap class. Graphics Mill for .NET will analyze the file extension. If this extension is recognized, image will be saved to appropriate file format. For example, if you specify name output.jpg, image will be saved as JPEG image, but if you change it into output.tif, it will be saved in TIFF format.
bitmap.Save("c:\result.jpg")
bitmap.Save(@"c:\result.jpg");
Also, if you need to control output image parameters, such as compression type, quality, etc, you can use descendants of class EncoderOptions. However you should remember, that type of encoder options class has higher priority when selecting output file type. For example, if you use filename output.png, but pass GifEncoderOptions class instance as encoder options, the output image will be saved in GIF format rather than PNG.
Here is a code example which saves image into file.
bitmap.Save("c:\result.jpg", New Aurigma.GraphicsMill.Codecs.JpegEncoderOptions(70, True))
bitmap.Save(@"c:\result.jpg", new Aurigma.GraphicsMill.Codecs.JpegEncoderOptions(70, true));
Graphics Mill for .NET provides more functionality to work with files than just Bitmap.Load and Bitmap.Save methods. The main limitation of these methods is that they cannot work with files that have more than one image (frame) inside. An examples of such files are multipage TIFF files (typically faxes or other documents), animated GIF files, etc. Load (and Save) always read (or write) only the first frame.
Also, these methods allow extracting only image data. Such information as EXIF and IPTC details cannot be read with Load method. Working with metadata is out of scope of this article, you can get more details at the separate topic.
And at last, these methods can be run in synchronous mode only. You cannot use Graphics Mill for .NET asynchronous features with them.
Alternative way is to use special classes from Aurigma.GraphicsMill.Codecs namespace - format readers and writers. They enables you using all features described above. Load and Save method of the Bitmap class actually use these classes inside.
Let's examine how to work with readers and writers.
To read data from file,Graphics Mill for .NET provides a number of classes called format readers. Each supported file type is presented by appropriate reader class, for example JpegReader, TiffReader, etc. All these classes implement IFormatReader interface and derived from FormatReader class.
To load image from file (i.e. get Bitmap class instance which contains this image), you should do the following:
You can obtain a reader instance in two ways. First of all, you can merely create it using constructor as well as any other .NET class. However if you do not know what file format you are loading, it is extremely inconvenient. That's why we provided an alternative: CreateFormatReader static method of the FormatManager class. It works as a class factory - you feed it a filename, and it returns a reader class of necessary type. This reader is already opened on this file, so you need not execute step 2 in this case.
You may wonder why to get Frame object instead of receiving Bitmap directly. In fact, Frame allows extracting additional data without having to load entire bitmap into memory. Reader starts loading image as soon as you call GetBitmap(Bitmap) (not during LoadFrame(Int32)). This way you can read, for example, width and height of the image in extremely fast manner.
It is a time to see a code example. This code snippet demonstrates how to split multipage TIFF file into separate JPEG files:
Dim filename As String = "c:\multipage.tif" Dim reader As Aurigma.GraphicsMill.Codecs.FormatReader = _ Aurigma.GraphicsMill.Codecs.FormatManager.CreateFormatReader(filename) Dim bitmap As New Aurigma.GraphicsMill.Bitmap For i As Integer = 0 To reader.FrameCount - 1 Dim frame As Aurigma.GraphicsMill.Codecs.Frame = reader.LoadFrame(i) frame.GetBitmap(bitmap) frame.Dispose() bitmap.Save("c:\frame_" & i & ".jpg") Next bitmap.Dispose() reader.Dispose()
string filename = @"c:\multipage.tif"; using (Aurigma.GraphicsMill.Codecs.IFormatReader reader = Aurigma.GraphicsMill.Codecs.FormatManager.CreateFormatReader(filename)) { using (Aurigma.GraphicsMill.Bitmap bitmap = new Aurigma.GraphicsMill.Bitmap()) { for (int i = 0; i < reader.FrameCount - 1; i++) { using (Aurigma.GraphicsMill.Codecs.IFrame frame = reader.LoadFrame(i)) { frame.GetBitmap(bitmap); bitmap.Save(@"c:\frame_" + i.ToString() + ".jpg"); } } } }
To write data into files, Graphics Mill for .NET has a set of classes called format writers. As in case of readers, each format supported for writing is presented by writer class, e.g. JpegWriter, GifWriter, etc. All writers implement IFormatWriter interface and have base class FormatWriter.
Writing files with format writer consists of the following steps:
Here is a code example which creates animated GIF file:
Dim dir As String = "C:\Documents and Settings\All Users\Documents\My Pictures\Sample Pictures\" Dim images As String() = {"Blue hills.jpg", "Sunset.jpg", "Water lilies.jpg", "Winter.jpg"} Dim image As String Dim bitmap As New Aurigma.GraphicsMill.Bitmap Dim writer As New Aurigma.GraphicsMill.Codecs.GifWriter("C:\Slideshow.gif") For Each image In images bitmap.Load(dir & image) bitmap.ColorManagement.PaletteEntryCount = 32 bitmap.ColorManagement.ConvertToIndexed(8, Aurigma.GraphicsMill.ColorPaletteType.Adaptive, _ Nothing) Dim frame As New Aurigma.GraphicsMill.Codecs.GifFrame frame.Delay = 100 frame.SetBitmap(bitmap) writer.AddFrame(frame) frame.Dispose() Next bitmap.Dispose() writer.Dispose()
string dir = @"C:\Documents and Settings\All Users\Documents\My Pictures\Sample Pictures"; string[] images = {"Blue hills.jpg", "Sunset.jpg", "Water lilies.jpg", "Winter.jpg"}; using (Aurigma.GraphicsMill.Bitmap bitmap = new Aurigma.GraphicsMill.Bitmap()) { using (Aurigma.GraphicsMill.Codecs.GifWriter writer = new Aurigma.GraphicsMill.Codecs.GifWriter(@"C:\Slideshow.gif")) { foreach (string image in images) { bitmap.Load(dir + image); bitmap.ColorManagement.PaletteEntryCount = 32; bitmap.ColorManagement.ConvertToIndexed(8, Aurigma.GraphicsMill.ColorPaletteType.Adaptive, null); using(Aurigma.GraphicsMill.Codecs.GifFrame frame = new Aurigma.GraphicsMill.Codecs.GifFrame()) { frame.Delay = 100; frame.SetBitmap(bitmap); writer.AddFrame(frame); } } } }
If you need display a thumbnail for an image file, there is better way than loading the image and applying Resize transform after that. You can read thumbnail "on-the-fly". It means that resizing will be applied directly during image decoding. This way we noticeable reduce memory overhead and increase the performance, especially for large images.
Both Bitmap class and format readers allow extracting thumbnails in such fast way.
To get a thumbnail through Bitmap class just call LoadThumbnail method instead of Load. In addition to the filename or stream, you should pass desired dimensions of the thumbnail. Note, the thumbnail preserves aspect ratio of the original image, so its actual dimensions may be smaller than specified. In other word, the arguments you pass into this method specify the rectangle to fit the thumbnail in. The code below demonstrates how to use it.
'Resize image proportionally to width not larger then 100 bitmap.LoadThumbnail("c:\Mountain.jpg", 100, 0) 'Resize image proportionally to height not larger then 100 'bitmap.LoadThumbnail("c:\Mountain.jpg", 0, 100) 'Resize image proportionally to fit in rectangle 100x100 'bitmap.LoadThumbnail("c:\Mountain.jpg", 100, 100)
//Resize image proportionally to width not larger then 100 bitmap.LoadThumbnail(@"c:\Mountain.jpg", 100, 0); //Resize image proportionally to height not larger then 100 //bitmap.LoadThumbnail(@"c:\Mountain.jpg", 0, 100); //Resize image proportionally to fit in rectangle 100x100 //bitmap.LoadThumbnail(@"c:\Mountain.jpg", 100, 100);
To load thumbnails through the readers, you should use method GetThumbnail(Bitmap, Int32, Int32) of the Frame (instead of GetBitmap(Bitmap)). It works in the same way as LoadThumbnail method of the Bitmap class (and actually used inside of this method).
Dim filename As String = "c:\mountain.jpg" Dim thumbnail As New Aurigma.GraphicsMill.Bitmap ' Create appropriate format reader. Dim reader As Aurigma.GraphicsMill.Codecs.FormatReader = _ Aurigma.GraphicsMill.Codecs.FormatManager.CreateFormatReader(filename) ' LoadFrame returns a frame object. From this frame we can get a thumbnail. Dim frame As Aurigma.GraphicsMill.Codecs.Frame = reader.LoadFrame(0) frame.GetThumbnail(thumbnail, 120, 120) frame.Dispose() reader.Dispose()
string filename = @"c:\mountain.jpg"; Aurigma.GraphicsMill.Bitmap thumbnail = new Aurigma.GraphicsMill.Bitmap(); // Create appropriate format reader. using (Aurigma.GraphicsMill.Codecs.IFormatReader reader = Aurigma.GraphicsMill.Codecs.FormatManager.CreateFormatReader(filename)) { // LoadFrame returns a frame object. From this frame we can get a bitmap. using (Aurigma.GraphicsMill.Codecs.IFrame frame = reader.LoadFrame(0)) { frame.GetThumbnail(thumbnail, 120, 120); } }
If you work with digital photos or other kind of images that store EXIF information, you can use even more fast way for getting thumbnails - extracting pre-created thumbnails from EXIF. This is out of the scope of this topic, read article Loading Thumbnails from EXIF Metadata for more details.
With Graphics Mill for .NET you need not do additional steps to load or save embedded color management profiles. If file contains the profile, and you load this file, you can get access to this profile through ColorProfile property of the Bitmap class. When you save this bitmap to the format that supports color profiles, embedded profile will be saved. You can change this profile, or even detach it (by setting null into this property).
Note, when you modify ColorProfile property, pixels are not changed to fit new color profile. To do it, you should use properties and methods exposed by ColorManagement property of the Bitmap class. You can read more detailed about color management in the article Using Color Management in Graphics Mill for .NET.