你的位置:首页 > 信息动态 > 新闻中心
信息动态
联系我们

读取照片信息

2021/12/18 18:20:53
# !/usr/bin/python3
# coding: utf-8
import json
import os
import traceback

import exifread
import requests


def parse_gps_express(gps_express):
    '''
    GPS坐标表达式转数值
    :param gps_express: GPS坐标表达式 [1,2,3/4]
    :return: GPS坐标数值 1.033542
    '''
    try:
        express = str(gps_express).replace(" ", "").replace("[", "").replace("]", "")
        parts = express.split(",")
        subpart = parts[2].split("/")

        degrees = float(parts[0])
        minutes = float(parts[1])
        seconds = float(subpart[0]) / float(subpart[1])
        return degrees + minutes / 60 + seconds / 3600
    except:
        raise Exception("Error information for the picture")


def photo_gps(photo_path):
    '''
    照片拍摄地GPS坐标
    :param photo_path: 照片的磁盘路径
    :return: 照片的 (GPS经度,GPS纬度)
    '''
    if not os.path.isfile(photo_path):
        raise Exception("File is not exist")

    with open(photo_path, 'rb') as f:
        exif_dict = exifread.process_file(f)
        longitude_ref = str(exif_dict["GPS GPSLongitudeRef"]).strip()
        longitude = parse_gps_express(str(exif_dict["GPS GPSLongitude"]))
        latitude_ref = str(exif_dict["GPS GPSLatitudeRef"]).strip()
        latitude = parse_gps_express(str(exif_dict["GPS GPSLatitude"]))

    lng = longitude if "E" == longitude_ref else 0 - longitude
    lat = latitude if "N" == latitude_ref else 0 - latitude
    return lng, lat


def convert_gps(gps_coordinates):
    '''
    坐标转换:GPS转高德
    :param gps_coordinates: 多个位置(GPS经度,GPS纬度)的集合
    :return: 多个位置(高德经度,高德纬度)的集合
    '''
    try:
        coordinates = "|".join(gps_coordinates)  # 最多批量查询40个
        token = "cb1c527f67df87bdc3a72f8a75987e62"  # 自行申请,免费

        url = "https://restapi.amap.com/v3/assistant/coordinate/convert" \
              "?locations={0}&key={1}&coordsys=gps&output=json".format(coordinates, token)

        response = requests.get(url)  # 个人开发者访问限流:100000次/日
        result = json.loads(response.text)
        if "1" == result["status"]:
            return result["locations"].split(";")
        else:
            raise Exception(result["info"])
    except Exception as e:
        raise e


def map_address(gd_coordinates):
    '''
    逆地理编码(高德坐标转地址)
    :param gd_coordinates:多个位置(高德经度,高德纬度)的集合
    :return:多个位置地址信息的集合
    '''
    try:
        coordinates = "|".join(gd_coordinates)  # 最多批量查询20个
        token = "cb1c527f67df87bdc3a72f8a75987e62"  # 自行申请,免费
        batch = "true" if len(gd_coordinates) > 1 else "false"

        url = "https://restapi.amap.com/v3/geocode/regeo" \
              "?location={0}&key={1}&batch={2}&radius=500&extensions=base&output=json".format(coordinates, token, batch)

        response = requests.get(url)  # 个人开发者访问限流:6000次/日
        result = json.loads(response.text)
        if "1" == result["status"]:
            address = []
            if "true" == batch:
                add_lst = list(result["regeocodes"])
                for add in add_lst:
                    address.append(add["formatted_address"])
            else:
                fmt_add = result["regeocode"]["formatted_address"]
                address.append(fmt_add)
            return address
        else:
            raise Exception(result["info"])
    except Exception as e:
        raise e


if __name__ == '__main__':
    try:
        lng1, lat1 = photo_gps("3.jpg")
        lng2, lat2 = photo_gps("3.jpg")
        lng3, lat3 = photo_gps("3.jpg")

        gps_coordinates = list()
        gps_coordinates.append("%s,%s" % (lng1, lat1))
        gps_coordinates.append("%s,%s" % (lng2, lat2))
        gps_coordinates.append("%s,%s" % (lng3, lat3))

        gd_coordinates = convert_gps(gps_coordinates)
        addresses = map_address(gd_coordinates)
        for add in addresses:
            print(add)
    except:
        traceback.print_exc()
# -*- coding: utf-8 -*-
# @Date     : 2020/02/22 13:59

import requests
import exifread


class GetPhotoInfo:
    def __init__(self, photo):
        self.photo = photo
        # 百度地图ak
        self.ak = '3iVKI77ap5Tb2M2FIGS1gvEtcSzD3yWZ'
        self.location = self.get_photo_info()

    def get_photo_info(self, ):
        with open(self.photo, 'rb') as f:
            tags = exifread.process_file(f)
        try:
            # 打印照片其中一些信息
            print('拍摄时间:', tags['EXIF DateTimeOriginal'])
            print('照相机制造商:', tags['Image Make'])
            print('照相机型号:', tags['Image Model'])
            print('照片尺寸:', tags['EXIF ExifImageWidth'], tags['EXIF ExifImageLength'])
            # 拿到的是度分秒的经纬度,需要转化为十进制的经纬度
            # 转换公式为    度 + 分 / 60 + 秒 / 3600
            # 纬度
            lat_ref = tags["GPS GPSLatitudeRef"].printable
            lat = tags["GPS GPSLatitude"].printable[1:-1].replace(" ", "").replace("/", ",").split(",")
            lat = float(lat[0]) + float(lat[1]) / 60 + float(lat[2]) / float(lat[3]) / 3600
            if lat_ref != "N":
                lat = lat * (-1)
            # 经度
            lon_ref = tags["GPS GPSLongitudeRef"].printable
            lon = tags["GPS GPSLongitude"].printable[1:-1].replace(" ", "").replace("/", ",").split(",")
            lon = float(lon[0]) + float(lon[1]) / 60 + float(lon[2]) / float(lon[3]) / 3600
            if lon_ref != "E":
                lon = lon * (-1)
        except KeyError:
            return "ERROR:请确保照片包含经纬度等EXIF信息。"
        else:
            print("经纬度:", lat, lon)
            return lat, lon

    def get_location(self):
        url = 'http://api.map.baidu.com/reverse_geocoding/v3/?ak={}&output=json' \
              '&coordtype=wgs84ll&location={},{}'.format(self.ak, *self.location)
        response = requests.get(url).json()
        status = response['status']
        if status == 0:
            address = response['result']['formatted_address']
            print('详细地址:', address)
        else:
            print('baidu_map error')


if __name__ == '__main__':
    Main = GetPhotoInfo('F:\\python练习\\41EC18077B90402F1BF6702448D40197.jpg')
    Main.get_location()