Comment 8 for bug 389960

Revision history for this message
robinmills (robinmills) wrote :

Hello Jacques

What a helpful response. Thank you very much. We're on the same page now.

I modified your script (and called it foo2.py and it operates on file foo.jpg). I copied a 'NOT geotagged file' RA.jpg to foo.jpg, added the GPSLongitude 22deg/33'/44" using surd and pyexiv2.Rational(). Exiv2 reports the result correctly.

650 /Users/rmills> cp RA.jpg foo.jpg ; python foo2.py ; exiv2 -pt foo.jpg | grep GPSLong
22d 33' 44"
Exif.GPSInfo.GPSLongitude Rational 3 22deg 33' 44"
651 /Users/rmills>

I think the issue is when you write and immediately attempt to report the metadata, the read is wrong (however the data's good!). The work around for the moment, is to close and re-open the file before attempting to read the metadata.

####
# NOT GOOD
img=pyexiv2.Image(bla..bla)
img.readMetadata()
img['Exif.GPSInfo.GPSLongitude' ] = [ .... ] ;
print img['Exif.GPSInfo.GPSLongitude'] # bad

####
# GOOD
img=pyexiv2.Image(bla..bla)
img.readMetadata()
img['Exif.GPSInfo.GPSLongitude' ] = [ .... ] ;
img.writeMetadata()

img=pyexiv2.Image(bla..bla)
img.readMetadata() ;
print img['Exif.GPSInfo.GPSLongitude']

I'm off to bed now (it's 00:56 here in California). Let's wait to see what Olivier says when he gets to work.

foo2.py

#!/usr/bin/env python
import pyexiv2
import surd

# img=pyexiv2.Image('foo.jpg')
# img.readMetadata()

# Check the longitude tag (as expected, the result is a tuple of 3 rationals):
# print img['Exif.GPSInfo.GPSLongitude']
# (<pyexiv2.Rational instance at 0xa560dac>, <pyexiv2.Rational instance at 0xa560c6c>, <pyexiv2.Rational instance at 0xa560e6c>)

# 3. Modify the tag:
# img['Exif.GPSInfo.GPSLongitude']=(pyexiv2.Rational(3,1),pyexiv2.Rational(44,1),pyexiv2.Rational(5615,100))

# 4. Check the modification:
# print img['Exif.GPSInfo.GPSLongitude']
# 0/1

##
# Ration number support
def R(f):
 """R(float) - get a Rational number for a float"""
 s = surd.surd(float(f))
 return pyexiv2.Rational(s.num,s.denom)

def d(angle):
 """d(any) - get degrees from a number :eg d(33.41) -> 33"""
 return int(angle)

def m(angle):
 """m(any) - get minutes from a number :eg d(33.41) -> 24"""
 return int( angle*60 - d(angle)* 60)

def s(angle):
 """s(any) - get seconds from a number :eg s(33.41) -> 36"""
 return int( angle*3600 - d(angle)*3600 - m(angle)*60 )

##
#
def f(r):
    return float(r.numerator)/float(r.denominator)

##
#
def ff(x):
    return f(x[0])+ (f(x[1])/60.0) + (f(x[2])/3660.0)

##
#
def fs(x):
    return str( int(f(x[0])) ) + "d " +\
            str( int(f(x[1])) ) + "' " +\
            str( int(f(x[2])) ) + '" '

# Create an image object and read the metadata:
img=pyexiv2.Image('foo.jpg')
img.readMetadata()

lon = 22.0 + 33.0/60.0 + 44.0/3600.0;
img['Exif.GPSInfo.GPSLongitude' ] = [R(d(lon)),R(m(lon)),R(s(lon))]
img.writeMetadata()
##
# here's the bandit!
# print fs(img['Exif.GPSInfo.GPSLongitude'])

img=pyexiv2.Image('foo.jpg')
img.readMetadata()
print fs(img['Exif.GPSInfo.GPSLongitude'])