Reputation: 41
Have now found a program for batch editing which will help me get back in control over my mountain of picture files. Its flipside is that parts of the metadata disappear in the editing. I'm not crying over lost advanced camera settings, but a couple of things I want to preserve are photo date and camera model.
To retrieve selected information was easily done with the method:
Set objShellApp = CreateObject("Shell.Application")
Set objFolder = objShellApp.Namespace(strFolder)
Set objFolderItem = objFolder.ParseName(strFile)
... followed by...
Cells(2,iColumn).Value = objFolder.getdetailsof(objFolderItem, 12) '(12 = photo taken)*<br>
Cells(3,iColumn).Value = objFolder.getdetailsof(objFolderItem, 30) '(30 = camera model)
(... etc with selected details)
In a loop through a folder the result will be a worksheet with the file names and their metadata in a table... and that's where I am now. I'm searching and I'm searching and the only thing I seem to find are different ways to retrieve the information, but what I want to know is how to put it back into a file.
Thanks in advance.
/Nick
Upvotes: 4
Views: 584
Reputation: 1586
You can use the WIA object to read and write meta data in image files.
For example, the following code writes GPS data to a JPG file;
Sub Write_Lon_Lat_Alt_ExifData()
' Haluk - 03/04/2024
' Reference : Microsoft Windows Image Acquistion Library V2.0
Dim Longitude As Double, Latitude As Double, Altitude As Long, Img As WIA.ImageFile, IP As WIA.ImageProcess, V As WIA.Vector
Dim r1 As New Rational, r2 As New Rational, r3 As New Rational, rAlt As New Rational
Dim myFile As Variant, NewFile As String
Dim Deg As Integer, Min As Integer, Sec As Double
' GPS Data to be written to the image file
Longitude = 24.858
Latitude = 36.761
Altitude = 1071
Set Img = New WIA.ImageFile
Set IP = New WIA.ImageProcess
Set V = New WIA.Vector
myFile = Application.GetOpenFilename("Image Files (*.jpg), *.jpg")
If myFile = False Then Exit Sub
NewFile = "New_" & Dir(myFile)
NewFile = Replace(myFile, Dir(myFile), NewFile)
If Dir(NewFile) <> "" Then Kill NewFile
Img.LoadFile myFile
IP.Filters.Add (IP.FilterInfos("Exif").FilterID)
' Begin writing Longitude to Image file
' ------------------------------------
IP.Filters(1).Properties("ID") = 4
IP.Filters(1).Properties("Type") = VectorOfUnsignedRationalsImagePropertyType '= 1106
Call Convert_LatLon(Longitude, Deg, Min, Sec)
' Set longitude as vector of unsigned rationals (r1= Degrees, r2= Minutes, r3= Seconds)
r1.Numerator = Deg
r1.Denominator = 1
r2.Numerator = Min
r2.Denominator = 1
' Displaying seconds as Integer
' r3.Numerator = Sec
' r3.Denominator = 1
' Displaying seconds as Double
r3.Numerator = Sec * 100
r3.Denominator = 100
V.Add r1, 0
V.Add r2, 0
V.Add r3, 0
IP.Filters(1).Properties("Value") = V
Set Img = IP.Apply(Img)
' End of writing Longitude to Image file
' ----------------------------------
'
'
' Begin writing Latitude to Image file
' ------------------------------------
IP.Filters(1).Properties("ID") = 2
IP.Filters(1).Properties("Type") = VectorOfUnsignedRationalsImagePropertyType '= 1106
Call Convert_LatLon(Latitude, Deg, Min, Sec)
' Set latitude as vector of unsigned rationals (r1= Degrees, r2= Minutes, r3= Seconds)
r1.Numerator = Deg
r1.Denominator = 1
r2.Numerator = Min
r2.Denominator = 1
' Displaying seconds as Integer
' r3.Numerator = Sec
' r3.Denominator = 1
' Displaying seconds as Double
r3.Numerator = Sec * 100
r3.Denominator = 100
' Vector object must be "cleared" or set as "New Wia.Vector" before using again, otherwise old rational values (r1, r2, r3) are retained
V.Clear
V.Add r1, 0
V.Add r2, 0
V.Add r3, 0
IP.Filters(1).Properties("Value") = V
Set Img = IP.Apply(Img)
' End of writing Latitude to Image file
' ----------------------------------
'
'
' Begin writing Altitude to Image file
' ------------------------------------
IP.Filters(1).Properties("ID") = 6
IP.Filters(1).Properties("Type") = RationalImagePropertyType ' = 1006
' Set altitude as rational with denominator = 1
rAlt.Numerator = Altitude
rAlt.Denominator = 1
IP.Filters(1).Properties("Value") = rAlt
Set Img = IP.Apply(Img)
' End of writing Altitude to Image file
' ----------------------------------
'
' Writing Longitude, Latitude and Altitude to image file is finnished, now save the file as a new file...
NewFile = "New_" & Dir(myFile)
NewFile = Replace(myFile, Dir(myFile), NewFile)
Img.SaveFile NewFile
End Sub
'
Function Convert_LatLon(Decimal_Deg As Double, Degrees As Integer, Minutes As Integer, Seconds As Double)
Degrees = Int(Decimal_Deg)
Minutes = Int((Decimal_Deg - Degrees) * 60)
Seconds = ((Decimal_Deg - Degrees) * 60 - Minutes) * 60
End Function
Upvotes: 0
Reputation: 97
what you want to do is modify imagefile tags/properties via VBA, which is not supported. Shell32.Folder
only supports reading and most of the methods are read-only for Shell32.FolderItem
inside a folder object.
The only way to modify the metadata is via external tool, exiftool.
but its a commandline tool so use this post to run it from excel vba.
Upvotes: 1