PB如何获取照相机的拍摄日期?
如题,用PB如何获取照相机的拍摄日期?
网上查了很多资料,基本上需要获取照片的Exif资料,如果用C#、Java好像很简单,但是用PB似乎没有提及,而且查了很多没有现成的Dll调用。
目前我用了一个非常笨的办法,通过用EditPlus打开照片文件,发现照相日期通常在最前的1000字节里,用以下代码暂时可以提取到拍摄日期,但是绝非好方法。
请大家发表完美的解决办法,最好能用什么方法可以获取到exif资料。
Long ll_file_num, ll_file_len, ll_i
Blob lb_photo
String ls_date
DateTime ldt_date
//打开文件
ll_file_num = FileOpen(ls_docname, StreamMode!, Read!, LockRead!)
//把照片写到Blob中,注意FileRead一次只能读取32765个字节,此处读取一次已够用
ll_file_len = FileRead(ll_file_num, lb_photo)
FileClose(ll_file_num)
//提取拍摄日期
For ll_i = 1 To 32765
ls_date = String(blobmid(lb_photo,ll_i,10),EncodingUTF8!)
If IsDate(ls_date) Then
ldt_date = DateTime(String(blobmid(lb_photo,ll_i,20),EncodingUTF8!))
Exit
End if
Next
PB?照片?拍摄日期
[解决办法]
不同的图片格式位置会有区别的,你可以参考一下VB的标准实现
Private Type GdiplusStartupInput
GdiplusVersion As Long
DebugEventCallback As Long
SuppressBackgroundThread As Long
SuppressExternalCodecs As Long
End Type
Private Type PropertyItem
propId As Long ' ID of this property
Length As Long ' Length of the property value, in bytes
Type As Long ' Type of the value, as one of TAG_TYPE_XXX defined above
Value As Long ' property value
End Type
Private Declare Function GdiplusStartup Lib "gdiplus" (Token As Long, inputbuf As GdiplusStartupInput, Optional ByVal outputbuf As Long = 0) As Long
Private Declare Sub GdiplusShutdown Lib "gdiplus" (ByVal Token As Long)
Private Declare Function GdipLoadImageFromFile Lib "gdiplus" (ByVal FileName As Long, hImage As Long) As Long
Private Declare Function GdipDisposeImage Lib "gdiplus" (ByVal Image As Long) As Long
Private Declare Function GdipGetPropertyCount Lib "gdiplus" (ByVal Image As Long, numOfProperty As Long) As Long
Private Declare Function GdipGetPropertyIdList Lib "gdiplus" (ByVal Image As Long, ByVal numOfProperty As Long, list As Long) As Long
Private Declare Function GdipGetPropertyItemSize Lib "gdiplus" (ByVal Image As Long, ByVal propId As Long, Size As Long) As Long
Private Declare Function GdipGetPropertyItem Lib "gdiplus" (ByVal Image As Long, ByVal propId As Long, ByVal propSize As Long, Buffer As Long) As Long
Private Declare Function GdipGetPropertySize Lib "gdiplus" (ByVal Image As Long, totalBufferSize As Long, numProperties As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (lpDst As Any, lpSrc As Any, ByVal ByteLength As Long)
Private Function GetPhotoDate(ImagePath As String) As String
Dim Bitmap As Long
Dim Token As Long
Dim Index As Long
Dim PropertyCount As Long
Dim ItemSize As Long
Dim Prop As PropertyItem
Dim GdipInput As GdiplusStartupInput
Const PropertyTagExifDTOrig As Long = &H9003& ' Date & time of original
GdipInput.GdiplusVersion = 1
GdiplusStartup Token, GdipInput
GdipLoadImageFromFile StrPtr(ImagePath), Bitmap
GdipGetPropertyCount Bitmap, PropertyCount
ReDim PropertyList(PropertyCount - 1) As Long
GdipGetPropertyIdList Bitmap, PropertyCount, PropertyList(0)
For Index = 0 To PropertyCount - 1
GdipGetPropertyItemSize Bitmap, PropertyList(Index), ItemSize
ReDim Buffer(ItemSize - 1) As Byte
GdipGetPropertyItem Bitmap, PropertyList(Index), ItemSize, ByVal VarPtr(Buffer(0))
CopyMemory Prop, ByVal VarPtr(Buffer(0)), Len(Prop)
ReDim Data(ItemSize - 16) As Byte
CopyMemory Data(0), ByVal Prop.Value, ItemSize - 16
Select Case PropertyList(Index)
Case PropertyTagExifDTOrig
GetPhotoDate = StrConv(Data, vbUnicode)
End Select
Next
GdipDisposeImage Bitmap
GdiplusShutdown Token
End Function