' Please do not remove :)
' Written by Kourosh Derakshan
'
Imports System
Imports System.IO
Imports System.Drawing
Imports System.Drawing.Imaging
Imports System.Runtime.InteropServices
Public MustInherit Class ExifThumbReader
<DllImport("gdiplus.dll", CharSet:=CharSet.Unicode, ExactSpelling:=True)> _
Private Shared Function GdipDisposeImage(ByVal image As IntPtr) As Integer
End Function
<DllImport("gdiplus.dll", CharSet:=CharSet.Unicode, ExactSpelling:=True)> _
Friend Shared Function GdipGetPropertyItem(ByVal image As IntPtr, ByVal propid As Integer, ByVal size As Integer, ByVal buffer As IntPtr) As Integer
End Function
<DllImport("gdiplus.dll", CharSet:=CharSet.Unicode, ExactSpelling:=True)> _
Friend Shared Function GdipGetPropertyItemSize(ByVal image As IntPtr, ByVal propid As Integer, <Out()> ByRef size As Integer) As Integer
End Function
<DllImport("gdiplus.dll", CharSet:=CharSet.Unicode, ExactSpelling:=True)> _
Friend Shared Function GdipLoadImageFromFile(ByVal filename As String, <Out()> ByRef image As IntPtr) As Integer
End Function
Private Const THUMBNAIL_DATA As Integer = 20507
Public Shared Function ReadThumb(ByVal imagePath As String) As Image
Dim image1 As Image
Dim ptr1 As IntPtr = IntPtr.Zero
Dim buffer As IntPtr = IntPtr.Zero
Dim ret As Integer = ExifThumbReader.GdipLoadImageFromFile(imagePath, ptr1)
Try
Dim thumbSize As Integer
If (ret <> 0) Then
Throw ExifThumbReader.createException(ret)
End If
ret = ExifThumbReader.GdipGetPropertyItemSize(ptr1, ExifThumbReader.THUMBNAIL_DATA, thumbSize)
If (ret = 19) Then
Return Nothing
End If
If (ret <> 0) Then
Throw ExifThumbReader.createException(ret)
End If
buffer = Marshal.AllocHGlobal(thumbSize)
If (buffer.Equals(IntPtr.Zero)) Then
Throw ExifThumbReader.createException(3)
End If
ret = ExifThumbReader.GdipGetPropertyItem(ptr1, ExifThumbReader.THUMBNAIL_DATA, thumbSize, buffer)
If (ret <> 0) Then
Throw ExifThumbReader.createException(ret)
End If
image1 = ExifThumbReader.convertFromMemory(buffer)
Finally
If (Not buffer.Equals(IntPtr.Zero)) Then
Marshal.FreeHGlobal(buffer)
End If
ExifThumbReader.GdipDisposeImage(ptr1)
End Try
Return image1
End Function
Private Shared Function createException(ByVal gdipErrorCode As Integer) As Exception
Select Case gdipErrorCode
Case 1
Return New ExternalException("Gdiplus Generic Error", -2147467259)
Case 2
Return New ArgumentException("Gdiplus Invalid Parameter")
Case 3
Return New OutOfMemoryException("Gdiplus Out Of Memory")
Case 4
Return New InvalidOperationException("Gdiplus Object Busy")
Case 5
Return New OutOfMemoryException("Gdiplus Insufficient Buffer")
Case 7
Return New ExternalException("Gdiplus Generic Error", -2147467259)
Case 8
Return New InvalidOperationException("Gdiplus Wrong State")
Case 9
Return New ExternalException("Gdiplus Aborted", -2147467260)
Case 10
Return New FileNotFoundException("Gdiplus File Not Found")
Case 11
Return New OverflowException("Gdiplus Over flow")
Case 12
Return New ExternalException("Gdiplus Access Denied", -2147024891)
Case 13
Return New ArgumentException("Gdiplus Unknown Image Format")
Case 18
Return New ExternalException("Gdiplus Not Initialized", -2147467259)
Case 20
Return New ArgumentException("Gdiplus Property Not Supported Error")
End Select
Return New ExternalException("Gdiplus Unknown Error", -2147418113)
End Function
Private Shared Function convertFromMemory(ByVal thumbData As IntPtr) As Image
Dim prop As propertyItemInternal = CType(Marshal.PtrToStructure(thumbData, GetType(propertyItemInternal)), propertyItemInternal)
Dim buffer As Byte() = prop.Value
Dim stream As New MemoryStream(buffer.Length)
stream.Write(buffer, 0, buffer.Length)
Return Image.FromStream(stream)
End Function
<StructLayout(LayoutKind.Sequential)> _
Private Class propertyItemInternal
Public ReadOnly Property Value() As Byte()
Get
Dim buffer1 As Byte() = New Byte(Me.len - 1) {}
Marshal.Copy(Me.valuePtr, buffer1, 0, Me.len)
Return buffer1
End Get
End Property
Public id As Integer
Public len As Integer
Public type As Short
Public valuePtr As IntPtr
End Class
End Class