移动测试基础 使用 Python 生成带经纬度信息的 JPG 图片

GUO · 2014年01月17日 · 2193 次阅读

图片管理类的 APP,测试的时候需要准备一些特定 GPS 信息和日期的图片来进行测试,而且最好图片能直观的体现出照片的 EXIF 信息
所以写了个 Python 的生成脚本

主要就是做了两件事情:
1.生成一张有文本信息的 JPG 图片
2.写入 EXIF 信息

生成照片需要 PIL 和 libjpeg

import Image
import ImageDraw
import ImageFont
def create_pic(path, text=[], type='jpeg'):
    img = Image.new("RGB", (2448, 3264), '#37b6ce')#颜色和大小
    draw = ImageDraw.Draw(img)
    font = ImageFont.truetype('ziti.ttf', 120)#ttf是字体,120是字号
    for h in range(0, len(text)):#多行文本
        draw.text((256, 256 + 120 * h), text[h], font=font)
    img.save(path, type)#保存
    # img.show()

读写 EXIF 信息需要 pyexiv2,获取 google 的经纬度需要 geopy
顺便说下经纬度的表示:
一般 exif 里看到的都是这样的 57°55'56.6",是度,分,秒这么展示的,google 上获取来的是十进制的 57.9323888888888
所以需要转换一下再写进去
公式:57°55'56.6" =57+55/60+56.6/3600=57.9323888888888

import fractions
import datetime
import os
import geopy
import pyexiv2
import time
template = pyexiv2.ImageMetadata('IMG_4408.JPG')
template.read()#exif信息很多,所以找个真正手机拍摄的照片当模版
googlev3=geopy.GoogleV3()
place,gps=googlev3.geocode(location)#获取gps信息,location写地名,比如‘北京王府井’,偶尔会被墙,最好挂个代理
def set_exif(path, date_time=None, gps=()):
    """
    datetime=2014:10:04 12:41:38
    geo=(lat=39.12315,lng=115.12231)
    """
    metadata = pyexiv2.ImageMetadata(path)
    metadata.read()
    for k in template.exif_keys:
        metadata[k] = pyexiv2.ExifTag(k, template[k].value)
    if not date_time:
        date_str=pyexiv2.utils.exif(date_time)
        metadata['Exif.Photo.DateTimeOriginal'] = date_str
        metadata['Exif.Photo.DateTimeDigitized'] = date_str
        metadata['Exif.Image.DateTime'] = date_str
    if len(geo)>0:
        c_lat = decimal2coordinate(geo[0], ['S', 'N'])
        c_lng = decimal2coordinate(geo[1], ['W', 'E'])
        metadata["Exif.GPSInfo.GPSLatitude"] = coordinate2rational(c_lat[0], c_lat[1], c_lat[2])
        metadata["Exif.GPSInfo.GPSLatitudeRef"] = c_lat[3]
        metadata["Exif.GPSInfo.GPSLongitude"] = coordinate2rational(c_lng[0], c_lng[1], c_lng[2])
        metadata["Exif.GPSInfo.GPSLongitudeRef"] = c_lng[3]
    else:
        metadata._delete_exif_tag("Exif.GPSInfo.GPSLatitude")
        metadata._delete_exif_tag("Exif.GPSInfo.GPSLatitudeRef")
        metadata._delete_exif_tag("Exif.GPSInfo.GPSLongitude")
        metadata._delete_exif_tag("Exif.GPSInfo.GPSLongitudeRef")
    metadata.write()


def decimal2coordinate(value, loc):
    """
    loc=lat => ["S", "N"],lng => ["W", "E"]
    retrun D,M,S,locate
    """
    if value < 0:
        loc_value = loc[0]
    elif value > 0:
        loc_value = loc[1]
    else:
        loc_value = ""
    abs_value = abs(value)
    deg = int(abs_value)
    t1 = (abs_value - deg) * 60
    min = int(t1)
    sec = round((t1 - min) * 60, 5)
    return (deg, min, sec, loc_value)

def coordinate2rational(D, M, S):
    return (fractions.Fraction(D, 1), fractions.Fraction(int((M + S / 60) * 100), 100), fractions.Fraction(0, 1))

共收到 1 条回复 时间 点赞
匿名 #1 · 2016年08月26日

请问一下,这里一段代码的用途是??

def coordinate2rational(D, M, S):
    return (fractions.Fraction(D, 1), fractions.Fraction(int((M + S / 60) * 100), 100), fractions.Fraction(0, 1))

可以直接在metadata["Exif.GPSInfo.GPSLatitude"]中添加经纬度吗??

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册