如何使python代码更清晰,优化和高效?

时间:2015-06-28 23:57:28

标签: python image python-3.x metadata extract

我在python 3中编写了一个程序,它从图像中提取元数据并使用此信息执行多项操作。其中一个功能是它将从元数据中提取GPS坐标,并使用谷歌地图的静态API绘制位置地图。

一切正常但我编写了这个非常混乱的代码来从找到的数据中提取坐标。如何清理此代码使其更有效?我还要感谢编写更好代码的任何提示。

提前致谢。

以下是输入数据的示例:(缩短以节省空间)

    EXIF BrightnessValue: 10
    EXIF ColorSpace: sRGB
    EXIF ComponentsConfiguration: YCbCr
    EXIF Contrast: Normal
    EXIF CustomRendered: Normal
    EXIF DateTimeDigitized: 2006:10:11 09:37:52
    EXIF DateTimeOriginal: 2006:10:11 09:37:52
    EXIF DigitalZoomRatio: 0
    EXIF ExifImageLength: 768
    EXIF ExifImageWidth: 1024
    EXIF ExifVersion: 0221
    EXIF ExposureBiasValue: 0
    EXIF ExposureMode: Auto Exposure
    EXIF ExposureProgram: Aperture Priority
    EXIF ExposureTime: 1/800
    EXIF FNumber: 71/10
    EXIF Flash: Flash did not fire, compulsory flash mode
    GPS GPSAltitude: 0
    GPS GPSAltitudeRef: 0
    GPS GPSLatitude: [33, 51, 2191/100]
    GPS GPSLatitudeRef: S
    GPS GPSLongitude: [151, 13, 1173/100]
    GPS GPSLongitudeRef: E
    GPS GPSVersionID: [0, 0, 2, 2]
    Image Artist:  
    Image Copyright:  
    Image DateTime: 2006:10:11 09:37:52
    Image ExifOffset: 346
    Image GPSInfo: 946
    Image ImageDescription: KONICA MINOLTA DIGITAL CAMERA
    Image Make: Konica Minolta Camera, Inc.
    Image Model: DiMAGE A2
    Image Orientation: Horizontal (normal)

以下是我的代码所做的(输出):

    ['33', '51', '2191/100', 'S', '151', '13', '1173/100', 'E']

它提取GPSLatitude,GPSLatitudeRef,GPSLongitude和GPSLongitudeRef,并按照上面显示的顺序将它们分配到单个列表中。 (顺序很重要,因为其他功能依赖于此列表的顺序)

代码段:

def coordinates_extractor():
    out = []

    lat1 = []
    lon1 = []

    lat2 = []
    lon2 = []

    lat3 = []
    lon3 = []

    lat4 = []
    lon4 = []

    ALL = []

    for tag in tags.keys():
        if tag not in ("JPEGThumbnail", "TIFFThumbnail", "EXIF MakerNote"):
            out += [("%s: %s" % (tag, tags[tag]))]
        out = sorted(out)

    for i in out:
        if "GPSLatitudeRef:" in i:
            lat1 += [i]
        if "GPSLatitude:" in i:
            lat1 += [i]

    for i in out:
        if "GPSLongitudeRef:" in i:
            lon1 += [i]
        if "GPSLongitude:" in i:
            lon1 += [i]

    for i in lat1:
        lat2 += i.split()

    del lat2[0]
    del lat2[0]
    del lat2[3]
    del lat2[3]

    for i in lat2:
        if "[" in i:
            lat3 += [i.replace("[", "")]
            continue
        if "]" not in i:
            lat3 += [i]
        if "]" in i:
            lat3 += [i.replace("]", "")]

    for i in lat3:
        if "," in i:
            lat4 += [i.replace(",", "")]
        if "," not in i:
            lat4 += [i]

    for i in lon1:
        lon2 += i.split()

    del lon2[0]
    del lon2[0]
    del lon2[3]
    del lon2[3]

    for i in lon2:
        if "[" in i:
            lon3 += [i.replace("[", "")]
            continue
        if "]" not in i:
            lon3 += [i]
        if "]" in i:
            lon3 += [i.replace("]", "")]

    for i in lon3:
        if "," in i:
            lon4 += [i.replace(",", "")]
        if "," not in i:
            lon4 += [i]

    LATANDLONG = lat4 + lon4

    return LATANDLONG

示例代码摘自:http://ptforum.photoolsweb.com/ubbthreads.php?ubb=download&Number=1024&filename=1024-2006_1011_093752.jpg

1 个答案:

答案 0 :(得分:0)

你可以尝试这样的事情。我包含了一个模拟的dict对象,以便在没有图像的情况下轻松运行。您只需将其删除并将其替换为我相信您正在使用的tags库提供的真实exifread对象。

# mock dictionary because I dont have your image
tags = {}
tags['GPS GPSLatitude'] =  [33, 51, 2191/100]
tags['GPS GPSLatitudeRef'] = 'S'
tags['GPS GPSLongitude'] = [151, 13, 1173/100]
tags['GPS GPSLongitudeRef'] = 'E'

out = []
wantedtags = ('GPS GPSLatitude', 'GPS GPSLatitudeRef', 'GPS GPSLongitude', 'GPS GPSLongitudeRef')

for tag in wantedtags:
    try:
        val = tags[tag]
        if isinstance(val, list):
            out.extend(map(str, val))
        else:
            out.append(val)
    except KeyError:
        print('Key %s does not exists' % tag)

print(out)

但需要注意的是输出与您预期的输出不完全相同。原因是文字2191/1001173/100在运行时被评估为除法语句并且在列表中被视为21& 11用于python 2和21.91& 11.73 for python 3.在python 2中使用from __future__ import division来获得更精确的除法结果。

exifread的行为是否有所不同?即它是否将此值存储在维持小数值的其他形式中,而不仅仅是普通的旧int?

我针对自己的模拟字典运行了自己的代码,输出与我的版本完全相同。