2012-05-29 17 views
5

Tôi định vị địa lý các ảnh JPEG sử dụng mô-đun pyexiv2 Python sử dụng mã tôi tìm thấy trong một câu trả lời SO khác (xem: What is the best way to geotag jpeg-images using Python?) và tôi có câu hỏi về giá trị GPSTag.Gắn thẻ địa lý JPEG với pyexiv2

Mã đưa ra trong các câu trả lời có những dòng sau:

exiv_image["Exif.Image.GPSTag"] = 654 
exiv_image["Exif.GPSInfo.GPSMapDatum"] = "WGS-84" 
exiv_image["Exif.GPSInfo.GPSVersionID"] = '2 0 0 0' 

Tôi đã nhìn vào Exiv2 documentation và thấy mô tả của GPSTag, GPSMapDatum, và GPSVersionID nhưng vẫn còn lẫn lộn về giá trị so với GPSTag.

Từ các tài liệu nó nói:

Một con trỏ tới IFD Thông tin GPS. Cấu trúc tương tác của IFD thông tin GPS, giống như của IFD Exif, không có dữ liệu hình ảnh.

Mô tả này không thực sự giải thích cách xác định giá trị sử dụng và tôi không thể tìm thấy mô tả tốt hơn về GPSTag trực tuyến.

Vì vậy, câu hỏi của tôi là:

  1. Cho một hình ảnh mới, làm thế nào để bạn xác định giá trị của Exif.Image.GPSTag?
  2. Tại sao mẫu mã sử dụng giá trị 654 (điều này có thể được trả lời bằng câu hỏi một)?

Cảm ơn sự giúp đỡ của bạn.

Trả lời

3

Cách tốt nhất để tin địa lý cho ảnh bằng pyexiv2 chắc chắn là với my program, GottenGeography ;-)

Nhưng nghiêm túc tuy nhiên, nếu bạn đang muốn truy cập dữ liệu GPS từ pyexiv2, mã trông như thế này:

GPS = 'Exif.GPSInfo.GPS' 
    try: 
     self.latitude = dms_to_decimal(
      *self.exif[GPS + 'Latitude'].value + 
      [self.exif[GPS + 'LatitudeRef'].value] 
     ) 
     self.longitude = dms_to_decimal(
      *self.exif[GPS + 'Longitude'].value + 
      [self.exif[GPS + 'LongitudeRef'].value] 
     ) 
    except KeyError: 
     pass 
    try: 
     self.altitude = float(self.exif[GPS + 'Altitude'].value) 
     if int(self.exif[GPS + 'AltitudeRef'].value) > 0: 
      self.altitude *= -1 
    except KeyError: 
     pass 

Và viết như sau:

self.exif[GPS + 'AltitudeRef'] = '0' if self.altitude >= 0 else '1' 
    self.exif[GPS + 'Altitude']  = Fraction(self.altitude) 
    self.exif[GPS + 'Latitude']  = decimal_to_dms(self.latitude) 
    self.exif[GPS + 'LatitudeRef'] = 'N' if self.latitude >= 0 else 'S' 
    self.exif[GPS + 'Longitude'] = decimal_to_dms(self.longitude) 
    self.exif[GPS + 'LongitudeRef'] = 'E' if self.longitude >= 0 else 'W' 
    self.exif[GPS + 'MapDatum']  = 'WGS-84' 

Với những chức năng hỗ trợ:

class Fraction(fractions.Fraction): 
    """Only create Fractions from floats. 

    >>> Fraction(0.3) 
    Fraction(3, 10) 
    >>> Fraction(1.1) 
    Fraction(11, 10) 
    """ 

    def __new__(cls, value, ignore=None): 
     """Should be compatible with Python 2.6, though untested.""" 
     return fractions.Fraction.from_float(value).limit_denominator(99999) 

def dms_to_decimal(degrees, minutes, seconds, sign=' '): 
    """Convert degrees, minutes, seconds into decimal degrees. 

    >>> dms_to_decimal(10, 10, 10) 
    10.169444444444444 
    >>> dms_to_decimal(8, 9, 10, 'S') 
    -8.152777777777779 
    """ 
    return (-1 if sign[0] in 'SWsw' else 1) * (
     float(degrees)  + 
     float(minutes)/60 + 
     float(seconds)/3600 
    ) 


def decimal_to_dms(decimal): 
    """Convert decimal degrees into degrees, minutes, seconds. 

    >>> decimal_to_dms(50.445891) 
    [Fraction(50, 1), Fraction(26, 1), Fraction(113019, 2500)] 
    >>> decimal_to_dms(-125.976893) 
    [Fraction(125, 1), Fraction(58, 1), Fraction(92037, 2500)] 
    """ 
    remainder, degrees = math.modf(abs(decimal)) 
    remainder, minutes = math.modf(remainder * 60) 
    return [Fraction(n) for n in (degrees, minutes, remainder * 60)] 

Mặc dù hiện tại tôi đang làm việc thay thế cho pyexiv2, sử dụng thư mục exb2 để truy cập thư viện exiv2 trực tiếp hơn, được gọi là GExiv2 và rất muốn có một số phản hồi về nó. Cả hai gexiv2 và pyexiv2 đều bao bọc xung quanh cùng một thư viện exiv2, nhưng sự khác biệt là pyexiv2 là một dự án rất lớn với rất nhiều keo, chỉ hoạt động trong python, và đang trên bờ vực bị bỏ rơi *; trong khi gexiv2 nhẹ và nhanh nhẹn, có thể truy cập từ bất kỳ ngôn ngữ lập trình nào, và được duy trì tốt nhờ sử dụng Shotwell.

Hy vọng điều này sẽ hữu ích!

* pyexiv2's author, Olivier Tilloy, has asked me for help with maintainership as he no longer has much time 
0

phiên bản của tôi, một chút dài ...

from fractions import Fraction 
import pyexiv2 

try: 
    metadata = pyexiv2.metadata.ImageMetadata(image_file) 
    metadata.read(); 
    thumb = metadata.exif_thumbnail 

    try: 
     latitude = metadata.__getitem__("Exif.GPSInfo.GPSLatitude") 
     latitudeRef = metadata.__getitem__("Exif.GPSInfo.GPSLatitudeRef") 
     longitude = metadata.__getitem__("Exif.GPSInfo.GPSLongitude") 
     longitudeRef = metadata.__getitem__("Exif.GPSInfo.GPSLongitudeRef") 

     latitude = str(latitude).split("=")[1][1:-1].split(" "); 
     latitude = map(lambda f: str(float(Fraction(f))), latitude) 
     latitude = latitude[0] + u"\u00b0" + latitude[1] + "'" + latitude[2] + '"' + " " + str(latitudeRef).split("=")[1][1:-1] 

     longitude = str(longitude).split("=")[1][1:-1].split(" "); 
     longitude = map(lambda f: str(float(Fraction(f))), longitude) 
     longitude = longitude[0] + u"\u00b0" + longitude[1] + "'" + longitude[2] + '"' + " " + str(longitudeRef).split("=")[1][1:-1] 

     latitude_value = dms_to_decimal(*metadata.__getitem__("Exif.GPSInfo.GPSLatitude").value + [metadata.__getitem__("Exif.GPSInfo.GPSLatitudeRef").value]); 
     longitude_value = dms_to_decimal(*metadata.__getitem__("Exif.GPSInfo.GPSLongitude").value + [metadata.__getitem__("Exif.GPSInfo.GPSLongitudeRef").value]); 

     print "--- GPS ---" 
     print "Coordinates: " + latitude + ", " + longitude 
     print "Coordinates: " + str(latitude_value) + ", " + str(longitude_value) 
     print "--- GPS ---" 
    except Exception, e: 
     print "No GPS Information!" 
     #print e 

    # Check for thumbnail 
    if(thumb.data == ""): 
     print "No thumbnail!" 
except Exception, e: 
    print "Error processing image..." 
    print e;