Creating thumbnails from the image is very wide-spread task. A good example is a file browser application. User can preview content of image files without having to open them. However generating thumbnails for multiple files may seem to be too long to him. It is especially actual when they browse large images, such as high-resolution photos (which can be, say, 5 or more megapixels). If you use traditional thumbnailing technique (image is loaded into memory and then resized), you will find out that this method has quite low performance. It is especially noticeable when you try to create multiple thumbnails at a time. If you use more advanced technique, provider with LoadThumbnail method of the Bitmap class, it will increase the performance, but thumbnails quality will be quite low.
Fortunately if you are working with digital photos, there is a solution which solves all these problems - reading thumbnail from EXIF data.
All the modern cameras writes a block of data called EXIF when capturing an image. EXIF contains a number of camera parameters, as well as other details (some models can even write GPS information). Along with this data most cameras saves a thumbnail which is displayed at the LCD display of this camera. So to get a thumbnail for a photo we need not read entire bitmap into memory, we can just take predefined thumbnail.
Graphics Mill for .NET provides easy-to-use support to EXIF fields. This code demonstrates how to extract a thumbnail from the EXIF:
Dim JpegReader As New Aurigma.GraphicsMill.Codecs.JpegReader("C:\IMG_0001.jpg") Dim thumbnail As Aurigma.GraphicsMill.Bitmap = _ JpegReader.Exif.Item(Aurigma.GraphicsMill.Codecs.ExifDictionary.Thumbnail) JpegReader.Dispose()
Aurigma.GraphicsMill.Bitmap thumbnail = null; using (Aurigma.GraphicsMill.Codecs.JpegReader jpegReader = new Aurigma.GraphicsMill.Codecs.JpegReader(@"C:\IMG_0001.jpg")) { thumbnail = (Aurigma.GraphicsMill.Bitmap) (jpegReader.Exif[Aurigma.GraphicsMill.Codecs.ExifDictionary.Thumbnail]); }
The only shortcoming of this thumbnailing approach is that not each image file has EXIF data. More over, in some files containing EXIF data thumbnail may be absent. So to handle this situation we should combine both techniques.
Also there is a limitation - you will get a thumbnail of the size which is stored inside EXIF (typically 160x120). To get a thumbnail of another size, you should resize it additionally.
This code example contains improvements that resolve both problems:
Const thumbnailSize As Integer = 120 Dim filePath As String = "C:\mountain.jpg" Dim jpegReader As New Aurigma.GraphicsMill.Codecs.JpegReader(filePath) Dim thumbnail As New Aurigma.GraphicsMill.Bitmap If (Not jpegReader.Exif Is Nothing) AndAlso (jpegReader.Exif.Contains( _ Aurigma.GraphicsMill.Codecs.ExifDictionary.Thumbnail)) Then thumbnail = jpegReader.Exif.Item(Aurigma.GraphicsMill.Codecs.ExifDictionary.Thumbnail) End If jpegReader.Dispose() If Not thumbnail Is Nothing Then 'Resize proportionaly If thumbnail.Width > thumbnail.Height Then thumbnail.Transforms.Resize(thumbnailSize, 0) Else thumbnail.Transforms.Resize(0, thumbnailSize) End If Else thumbnail = New Aurigma.GraphicsMill.Bitmap thumbnail.LoadThumbnail(filePath, thumbnailSize, thumbnailSize) End If
const int thumbnailSize = 120; string filePath = @"C:\mountain.jpg"; Aurigma.GraphicsMill.Bitmap thumbnail = null; using (Aurigma.GraphicsMill.Codecs.JpegReader jpegReader = new Aurigma.GraphicsMill.Codecs.JpegReader(filePath)) { if ((jpegReader.Exif != null) && (jpegReader.Exif.Contains( Aurigma.GraphicsMill.Codecs.ExifDictionary.Thumbnail))) { thumbnail = (Aurigma.GraphicsMill.Bitmap) (jpegReader.Exif[Aurigma.GraphicsMill.Codecs.ExifDictionary.Thumbnail]); } } if (thumbnail != null) { //Resize proportionaly if (thumbnail.Width > thumbnail.Height) { thumbnail.Transforms.Resize(thumbnailSize, 0); } else { thumbnail.Transforms.Resize(0, thumbnailSize); } } else { thumbnail = new Aurigma.GraphicsMill.Bitmap(); thumbnail.LoadThumbnail(filePath, thumbnailSize, thumbnailSize); }