我是靠谱客的博主 害羞纸飞机,最近开发中收集的这篇文章主要介绍【python初学者日记】用PIL批量给HEIC格式的照片,添加拍摄日期、拍摄地点的水印戳问题合集问题解决,觉得挺不错的,现在分享给大家,希望可以做个参考。
概述
【python初学者日记】用PIL批量给HEIC格式的照片,添加拍摄日期、拍摄地点的水印戳
- 问题合集
- 1、读取 HEIC 格式照片的拍摄信息
- 2、将已知坐标转码成具体省市地址的文字信息
- 3、将文字添加到HEIC格式的照片上
- 问题解决
- 一、问题分析
- 二、代码实现
最近在整理手机相册,发现以前在拍摄的时候,不喜欢给照片带水印,现在想在照片上面打上拍摄时间+地点的水印戳。之前有写过将exl中的内容,添加到照片的功能,所以这次的就简单多了。
问题合集
1、读取 HEIC 格式照片的拍摄信息
2、将已知坐标转码成具体省市地址的文字信息
3、将文字添加到HEIC格式的照片上
问题解决
一、问题分析
-
1、读取HEIC格式照片的拍摄信息:
- 现有版本python3.11,用exifread库即可将苹果导出的HEIC格式照片的拍摄信息。 2、将已知坐标转码成具体省市地址的文字信息:
-
这里我使用的是百度地图调起API,参考说明如图:
传送门: https://lbsyun.baidu.com/index.php?title=uri/api/web
注:此方法无需注册开发者,可以直接使用。
3、将文字添加到HEIC格式的照片上: - 这里偷个懒,我之前有写过将exl中的内容,添加到照片的功能,此处稍作修改即可实现功能。
二、代码实现
1、代码如下:
# -*- coding: utf-8 -*-
# 读取图片属性中的拍摄日期,并给图片添加拍摄日期、地点
import datetime
import os
import exifread
import requests
import json
from PIL import Image, ImageDraw, ImageFont, ImageFilter
from pillow_heif import register_heif_opener
register_heif_opener()
# 示例已知经纬度,利用百度地图,输出当前省市等信息
# http://api.map.baidu.com/geocoder?location=30.204891666666665,120.19970833333333&coord_type=gcj02&output=json
my_font = r"C:WindowsFontsSIMYOU.TTF"
startTime_program = datetime.datetime.now()
# 开始时间
# 定义一个换算函数,功能:将输入的度(时)分秒,经过换算,返回度(时)。例如输入[30, 12, 1761/100],返回30.204891666666665
def Conversion(data):
temp_data = [ele.strip() for ele in (str(data).replace('[', '').replace(']', '').split(','))]
new_data = eval(temp_data[-1]) / 3600 + int(temp_data[1]) / 60 + int(temp_data[0])
return new_data
# 在给定的照片中,提取时间戳:仅保留年月日;经纬度:通过在百度api上查找到省市,然后返回”年/月/日 省 市“的值。
def get_stamp(pic):
# exifread读出的经纬度是列表[度,分,秒],需要转换成单位为度的小数
# 获取图片拍摄时间
time = pic['Image DateTime']
# print(time) # 打印时间戳
time_stamp = str(time)[0:4] + "/" + str(time)[5:7] + "/" + str(time)[8:10]
# 从拍摄时间中,提取日期
# print(time_stamp) # 打印新格式的时间戳
latitude = Conversion(pic['GPS GPSLatitude'])
# 从图片提取纬度并将单位度分秒换算成度
# print(latitude)
# 打印纬度
longitude = Conversion(pic['GPS GPSLongitude'])
# 从图片提取经度并将单位度分秒换算成度
# print(longitude) # 打印经度
coordinates = str(latitude) + ',' + str(longitude)
# print(coordinates) # 打印坐标
query_adStr = "http://api.map.baidu.com/geocoder?location=" + coordinates + "&coord_type=gcj02&output=json"
# 注意此链接,根据百度开发者平台,此处改为以json格式输出,更方便后续解码
resp = requests.get(query_adStr)
# 向服务器请求数据
url_text = resp.content.decode()
# 读取源文件字节流,随后将该字节流编码为Unicode编码
location_data = json.loads(url_text)
# 用于解码 JSON 数据。该函数返回 Python 字段的数据类型
address = location_data.get('result').get(
'addressComponent')
# 在代码中找到addressComponent字段,此条可去浏览器粘贴链接查看:http://api.map.baidu.com/geocoder?location=30.204891666666665,120.19970833333333&coord_type=gcj02
province = address.get('province')
# 从获取的地址信息中,找到省份的值
city = address.get('city')
# 从获取的地址信息中,找到城市的值
stamp = str(time_stamp) + 'n' + ' ' + str(province[:-1]) + ' ' + str(city[:-1])
# 将时间戳、地址戳按格式整合
return stamp
# 返回新戳
# 定义在已给地址批量读图的信息,并存到数组里,并返回数组.修正:改为字典方式输出,即文件路径名:stamp
def pics_add_stamps(path):
stamps = {}
for each_pic in os.listdir(path):
if os.path.splitext(each_pic)[1] == '.heic':
each_pic_Path = path + "\" + each_pic
pic_data = exifread.process_file(open(each_pic_Path, 'rb'))
temp_stamp = get_stamp(pic_data)
stamp_key = each_pic_Path
stamp_data = temp_stamp
stamps[stamp_key] = stamp_data
return stamps
# 读照片,并将提取到的时间位置信息,加到照片上,并存到新的文件夹
def deal_pic_1by1(pic, text, pic_newPath):
# 打开初始图片
image = Image.open(pic)
# 设置字体
size = 100
# 定义字体大小
font = ImageFont.truetype(my_font, size)
# 设置字体的格式、大小
# 创建Draw对象:
draw = ImageDraw.Draw(image)
# 计算文字要放置的位置:image.size:像素(宽,高);image.size[0]是指照片的宽,即距离左边最大水平距离;image.size[1]是指照片的高,即距离上边最大垂直距离
site_x = image.size[0] - 650
# 距离左边水平距离:650像素(自定义,可根据自己喜好调整)
site_y = image.size[1] - 320
# 距离上边垂直距离:320像素(自定义,可根据自己喜好调整)
site = (site_x, site_y)
# 距离左上角距离
# 输出文字(可以连续写入):
draw.text(site, text, font=font, fill='#fff')
# 设置放置位置、文本内容、字体、颜色
# 模糊并保存:
image.filter(ImageFilter.BLUR)
namePath = os.path.basename(pic)
if not os.path.exists(pic_newPath):
# 判断存放图片的文件夹是否存在
os.makedirs(pic_newPath)
# 若图片文件夹不存在就创建
# 两种方式保存:
# image.save(pic_newPath + "/" + namePath)
# 以默认的图片格式来存储:保留原图所有信息,但是会压缩文件大小,文件保存时间和原图拍摄保存的时间一致
image.save(pic_newPath + "/" + namePath,
"PNG")
# 缺省原图大部分信息,如拍照时间地点等,生成新的图片,由于save不能直接将heic转换为其他格式,所以保存的格式仍然是和原图一样,heic
if __name__ == "__main__":
pic_path = r"F:qin_ipad_pic"
# 待处理的图片所在路径
pic_path_new = f"F:\qin_ipad_pic\qin_ipad_pic-NEW"
# 处理好的图片要保存的路径
n = 0
i = 1
# 将pic_path路径下的heic照片提取信息,返回值保存到pic_stamps,类型是字典{图片1路径:图片1时间戳+地点戳;图片2路径:图片2时间戳+地点戳,...}
pic_stamps = pics_add_stamps(pic_path)
# print("pic_stamps的类型是:", type(pic_stamps))
for item in pic_stamps:
data = pic_stamps.get(item)
# dict.get(item)
deal_pic_1by1(item, data, pic_path_new)
n += 1
print('共有{}个HEIC文件'.format(n))
endTime_program = datetime.datetime.now()
# 结束时间
print('本次处理照片一共用了:%0.2f秒' % (endTime_program - startTime_program).seconds)
2、运行结果如下:
最后
以上就是害羞纸飞机为你收集整理的【python初学者日记】用PIL批量给HEIC格式的照片,添加拍摄日期、拍摄地点的水印戳问题合集问题解决的全部内容,希望文章能够帮你解决【python初学者日记】用PIL批量给HEIC格式的照片,添加拍摄日期、拍摄地点的水印戳问题合集问题解决所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复