How to attach metadata for google photos for uploading legacy photos to google photos with GPS, ratings and descriptions.

The tool of choice for me is exiv2. It gives command line access to the various metadata attributes in JPEG files. (exiftool is another alternative.)

The metadata of files can be explored with a command such as:

exiv2 print -b -P XEI myfile.jpg

Ratings and Descriptions

These attributes are used by Windows explorer, were used by the depreciated Windows Photo Gallery, and are used by XnViewMp.

  • Rating: Xmp.xmp.Rating (windows and other tools uses this for the number of stars)
  • Description: Exif.Image.ImageDescription (windows uses this for ‘Title’ column in explorer)
  • Tags/Keywords: Xmp.dc.subject or Exif.Image.XPKeywords

To migrate from old XML metadata to embedded metadata I’ve used these commands:

exiv2 -M"add Xmp.xmp.Rating XmpText ${rating}" myfile.jpg
exiv2 -M"set Exif.Image.ImageDescription  Ascii '${desc}'" myfile.jpg
exiv2 -M"set Xmp.dc.subject  XmpBag ${tag}"  myfile.jpg
exiv2 -M"add Xmp.dc.subject  XmpBag ${tag}"  myfile.jpg

Google Photos, however uses a different metadata field for it’s description. To migrate from the ImageDescription tag I’ve used these commands:

desc=`exiv2 print -b -P t -g  Exif.Image.ImageDescription myfile.jpg`
exiv2 -M"set Iptc.Application2.Caption Ascii '${desc}'"  myfile.jpg

Geo tagging

Old digital cameras did not tag the location. For the mapping function of google photos to work the GPS info needs to be added.

One option is to use a tool such as GeoSetter.

However, as I already had tagged locations in metadata, such as Japan/Tokyo/Takao/Mt Takao I plugged them into a service such as gisgraphy and created a map such as:

{"Japan/Tokyo/Takao/Mt Takao"=>{"latitude"=>"35.625140", "longitude"=>"139.243641"},

Then in ruby a quick and dirty conversion to Exif tags can be done.

lat_ref = "North"
lat = gps["latitude"]
long_ref = "East"
long = gps["longitude"]
if lat =~ /^[\+\-]/
  if lat[0] == "-"
    lat_ref = "South"
  end
  lat=lat[1..-1]
end
if long =~ /^[\+\-]/
  if long[0] == "-"
    long_ref = "West"
  end
  long = long[1..-1]
end
def format_rat(set)
  return "#{set[0]}/1 #{set[1]}/1 #{(set[2]*10000).floor.to_i}/10000"
end
lat_rat = format_rat(split_raw(lat))
long_rat = format_rat(split_raw(long))


system("exiv2 -M\"set Exif.GPSInfo.GPSLatitudeRef  Ascii '#{lat_ref}'\"   '#{file}'")
system("exiv2 -M\"set Exif.GPSInfo.GPSLongitudeRef Ascii '#{long_ref}'\"  '#{file}'")
system("exiv2 -M\"set Exif.GPSInfo.GPSLatitude     Rational '#{lat_rat}'\"  '#{file}'")
system("exiv2 -M\"set Exif.GPSInfo.GPSLongitude    Rational '#{long_rat}'\" '#{file}'")

Google Photos respects these and displays old digital camera photos on the map.

Dates

Old film scans won’t even have a correct date. For those it’s usually possible to figure out the date, but not the time.

eventdate="2003:08:03"
exiv2 -M"set Exif.Image.DateTime  Ascii '${eventdate} 0:00:00'" myfile.jpg
exiv2 -M"set Exif.Photo.DateTimeOriginal  Ascii '${eventdate} 0:00:00'" myfile.jpg

Uploading

Use Gphotos Uploader.