|Title||Read an image file's EXIF orientation data in Visual Basic .NET|
|Description||This example shows how to read an image file's EXIF orientation data in Visual Basic .NET.|
|Keywords||graphics, files, image processing, EXIF, orientation, rotate image, example, example program, Windows Forms programming, Visual Basic .NET, VB.NET|
|Categories||Graphics, Graphics, Algorithms|
The EXchangeable Image File (EXIF) standard defines all sorts of information that a camera can add to a jpg file. For example, the camera may record latitude, longitude, altitude, date and time, focal length, shutter speed, and resolution. This example shows how to get an image's orientation information.
Note that not all cameras can set EXIF information and some that can may not unless you set the proper settings. The two pictures included with this example do contain EXIF orientation information so you can test the program.
The Image class (from which Bitmap inherits) provides two useful items for working with EXIF data: the PropertyIdList property, and the GetPropertyItem and SetPropertyItem methods.
The PropertyIdList property returns an array of integers giving the IDs of the properties stored in the image. You can use Array.IndexOf to try to find the index of a particular property's ID in this array. (If the image doesn't contain information for that property, Array.IndexOf returns -1.)
The GetPropertyItem method returns a PropertyItem object containing information about a property. You need to pass GetPropertyItem the ID of the item you want to retrieve.
The PropertyItem class has the properties Id (the property's ID), Len (the length in bytes of the property's value), Type (defines the type of data in the Value property), and Value (the value).
The SetPropertyItem method sets a property's value. Unfortunately there is no constructor for the PropertyItem class so you cannot create one from scratch. You can, however, get a PropertyItem from an image and modify it.
The orientation property's ID is 0x0112. The PropertyItem for the orientation property holds an array of bytes in its Value property, with the first byte giving the orientation. The following picture shows the meanings of the orientations demonstrated by the letter F.
The example program places EXIF methods in an ExifStuff module. Here's how it defines the orientation ID and the orientation values.
Private Const OrientationId As Integer = &H112
Public Enum ExifOrientations As Byte
Unknown = 0
TopLeft = 1
TopRight = 2
BottomRight = 3
BottomLeft = 4
LeftTop = 5
RightTop = 6
RightBottom = 7
LeftBottom = 8
The following code shows how the program gets the image's orientation.
' Return the image's orientation.
Public Function ImageOrientation(ByVal img As Image) As _
' Get the index of the orientation property.
Dim orientation_index As Integer = _
' If there is no such property, return Unknown.
If (orientation_index < 0) Then Return _
' Return the orientation value.
Return DirectCast(img.GetPropertyItem(OrientationId).Value(0), _
This code uses Array.IndexOf to see if the image's property ID list includes orientation. If the orientation ID is found, the method uses GetPropertyItem to get the corresponding PropertyItem object, gets its first Value entry, converts it into an ExifOrientations value, and returns the result.
The ExifStuff class also contains the following OrientationImage method, which returns an image showing the letter F in a particular orientation. You can download the example program that generated the orientation images shown earlier here. (Look at that example's code to see how it works.)
' Make an image to demonstrate orientations.
Public Function OrientationImage(ByVal orientation As _
ExifOrientations) As Image
Const size As Integer = 64
Dim bm As New Bitmap(size, size)
Using gr As Graphics = Graphics.FromImage(bm)
gr.TextRenderingHint = _
' Orient the result.
Select Case (orientation)
gr.ScaleTransform(-1, 1, MatrixOrder.Append)
gr.ScaleTransform(1, -1, MatrixOrder.Append)
' Translate the result to the center of the bitmap.
gr.TranslateTransform(size / 2, size / 2, _
Using string_format As New StringFormat()
string_format.LineAlignment = _
string_format.Alignment = StringAlignment.Center
Using the_font As New Font("Times New Roman", _
If (orientation = ExifOrientations.Unknown) _
gr.DrawString("?", the_font, _
Brushes.Black, 0, 0, string_format)
gr.DrawString("F", the_font, _
Brushes.Black, 0, 0, string_format)
This method demonstrates some interesting graphics transformations. First it creates a Bitmap and an associated Graphics object. Then depending on the desired orientation, it applies a transformation to the Graphics object to rotate and flip the drawing that follows.
Next the code applies a translation to center the resulting image in the Bitmap. Finally the method draws the letter F centered at the origin. The transformations rotate and flip the result and then translate it to center it in the Bitmap.
The main example program uses the ExifStuff methods in the following code to display an image, its orientation, and an oriented sample image containing the letter F.
' Open the file and read its orientation information.
Private Sub btnOpen_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnOpen.Click
' Open the file.
Dim bm As New Bitmap(txtFile.Text)
picOriginal.Image = bm
' Get the PropertyItems property from image.
Dim Orientation As ExifOrientations = _
lblOrientation.Text = Orientation.ToString()
picOrientation.Image = OrientationImage(Orientation)
The code opens a JPG file and displays it. It then calls ImageOrientation to get the image's orientation and displays it as a string. It then calls OrientationImage to get the oriented sample image and displays it.