
Python读取图片属性信息的实现方法
这篇文章介绍了利用Python读取图片属性信息的方法,读取的内容包括GPS 信息、图片分辨率、图片像素、设备商、拍摄设备等,有需要的朋友们可以参考借鉴。
本文是利用Python脚本读取图片信息,有几个说明如下:
1、没有实现错误处理
2、没有读取所有信息,大概只有 GPS 信息、图片分辨率、图片像素、设备商、拍摄设备等
3、简单修改后应该能实现暴力修改图片的 GPS 信息
4、但对于本身没有 GPS 信息的图片,实现则非常复杂,需要仔细计算每个描述符的偏移量
脚本运行后,读取结果如下
脚本读取的信息
这里和 Windows 属性查看器读到的内容完全一致
图片信息2
源码如下
# -*- coding:utf-8 -*-
import binascii
class ParseMethod(object):
@staticmethod
def parse_default(f, count, offset):
pass
@staticmethod
def parse_latitude(f, count, offset):
old_pos = f.tell()
f.seek(12 + offset)
latitude = [0,0,0]
for i in xrange(count):
byte = f.read(4)
numerator = byte.encode('hex')
byte = f.read(4)
denominator = byte.encode('hex')
latitude[i] = float(int(numerator, 16)) / int(denominator, 16)
print 'Latitude:\t%.2f %.2f\' %.2f\"' % (latitude[0], latitude[1], latitude[2])
f.seek(old_pos)
@staticmethod
def parse_longtitude(f, count, offset):
old_pos = f.tell()
f.seek(12 + offset)
longtitude = [0,0,0]
for i in xrange(count):
byte = f.read(4)
numerator = byte.encode('hex')
byte = f.read(4)
denominator = byte.encode('hex')
longtitude[i] = float(int(numerator, 16)) / int(denominator, 16)
print 'Longtitude:\t%.2f %.2f\' %.2f\"' % (longtitude[0], longtitude[1], longtitude[2])
f.seek(old_pos)
@staticmethod
def parse_make(f, count, offset):
old_pos = f.tell()
f.seek(12 + offset)
byte = f.read(count)
a = byte.encode('hex')
print 'Make:\t\t' + binascii.a2b_hex(a)
f.seek(old_pos)
@staticmethod
def parse_model(f, count, offset):
old_pos = f.tell()
f.seek(12 + offset)
byte = f.read(count)
a = byte.encode('hex')
print 'Model:\t\t' + binascii.a2b_hex(a)
f.seek(old_pos)
@staticmethod
def parse_datetime(f, count, offset):
old_pos = f.tell()
f.seek(12 + offset)
byte = f.read(count)
a = byte.encode('hex')
print 'DateTime:\t' + binascii.a2b_hex(a)
f.seek(old_pos)
# rational data type, 05
@staticmethod
def parse_xresolution(f, count, offset):
old_pos = f.tell()
f.seek(12 + offset)
byte = f.read(4)
numerator = byte.encode('hex')
byte = f.read(4)
denominator = byte.encode('hex')
xre = int(numerator, 16) / int(denominator, 16)
print 'XResolution:\t' + str(xre) + ' dpi'
f.seek(old_pos)
@staticmethod
def parse_yresolution(f, count, offset):
old_pos = f.tell()
f.seek(12 + offset)
byte = f.read(4)
numerator = byte.encode('hex')
byte = f.read(4)
denominator = byte.encode('hex')
xre = int(numerator, 16) / int(denominator, 16)
print 'YResolution:\t' + str(xre) + ' dpi'
f.seek(old_pos)
@staticmethod
def parse_exif_ifd(f, count, offset):
old_pos = f.tell()
f.seek(12 + offset)
byte = f.read(2)
a = byte.encode('hex')
exif_ifd_number = int(a, 16)
for i in xrange(exif_ifd_number):
byte = f.read(2)
tag_id = byte.encode('hex')
#print tag_id,
byte = f.read(2)
type_n = byte.encode('hex')
#print type_n,
byte = f.read(4)
count = byte.encode('hex')
#print count,
byte = f.read(4)
value_offset = byte.encode('hex')
#print value_offset
value_offset = int(value_offset, 16)
EXIF_IFD_DICT.get(tag_id, ParseMethod.parse_default)(f, count, value_offset)
f.seek(old_pos)
@staticmethod
def parse_x_pixel(f, count, value):
print 'X Pixels:\t' + str(value)
@staticmethod
def parse_y_pixel(f, count, value):
print 'y Pixels:\t' + str(value)
@staticmethod
def parse_gps_ifd(f, count, offset):
old_pos = f.tell()
f.seek(12 + offset)
byte = f.read(2)
a = byte.encode('hex')
gps_ifd_number = int(a, 16)
for i in xrange(gps_ifd_number):
byte = f.read(2)
tag_id = byte.encode('hex')
#print tag_id,
byte = f.read(2)
type_n = byte.encode('hex')
#print type_n,
byte = f.read(4)
count = byte.encode('hex')
#print count,
byte = f.read(4)
value_offset = byte.encode('hex')
#print value_offset
count = int(count, 16)
value_offset = int(value_offset, 16)
GPS_IFD_DICT.get(tag_id, ParseMethod.parse_default)(f, count, value_offset)
f.seek(old_pos)
IFD_dict = {
'010f' : ParseMethod.parse_make ,
'0110' : ParseMethod.parse_model ,
'0132' : ParseMethod.parse_datetime ,
'011a' : ParseMethod.parse_xresolution ,
'011b' : ParseMethod.parse_yresolution ,
'8769' : ParseMethod.parse_exif_ifd ,
'8825' : ParseMethod.parse_gps_ifd
}
EXIF_IFD_DICT = {
'a002' : ParseMethod.parse_x_pixel ,
'a003' : ParseMethod.parse_y_pixel
}
GPS_IFD_DICT = {
'0002' : ParseMethod.parse_latitude ,
'0004' : ParseMethod.parse_longtitude
}
with open('image.jpg', 'rb') as f:
byte = f.read(2)
a = byte.encode('hex')
print 'SOI Marker:\t' + a
byte = f.read(2)
a = byte.encode('hex')
print 'APP1 Marker:\t' + a
byte = f.read(2)
a = byte.encode('hex')
print 'APP1 Length:\t' + str(int(a, 16)) + ' .Dec'
byte = f.read(4)
a = byte.encode('hex')
print 'Identifier:\t' + binascii.a2b_hex(a)
byte = f.read(2)
a = byte.encode('hex')
print 'Pad:\t\t' + a
print
print 'Begin to print Header.... '
print 'APP1 Body: '
byte = f.read(2)
a = byte.encode('hex')
print 'Byte Order:\t' + a
byte = f.read(2)
a = byte.encode('hex')
print '42:\t\t' + a
byte = f.read(4)
a = byte.encode('hex')
print '0th IFD Offset:\t' + a
print 'Finish print Header'
print 'Begin to print 0th IFD....'
print
#print 'Total: ',
byte = f.read(2)
a = byte.encode('hex')
interoperability_number = int(a, 16)
#print interoperability_number
for i in xrange(interoperability_number):
byte = f.read(2)
tag_id = byte.encode('hex')
#print tag_id,
byte = f.read(2)
type_n = byte.encode('hex')
#print type_n,
byte = f.read(4)
count = byte.encode('hex')
#print count,
byte = f.read(4)
value_offset = byte.encode('hex')
#print value_offset
count = int(count, 16)
value_offset = int(value_offset, 16)
# simulate switch
IFD_dict.get(tag_id, ParseMethod.parse_default)(f, count, value_offset)
print
print 'Finish print 0th IFD....'
总结
利用Python读取图片属性信息的实现方法到这就基本结束了,大家都学会了吗?希望这篇文章对大家的学习或者工作带来一定的帮助,
数据分析咨询请扫描二维码
若不方便扫码,搜微信号:CDAshujufenxi
剖析 CDA 数据分析师考试题型:解锁高效备考与答题策略 CDA(Certified Data Analyst)数据分析师考试作为衡量数据专业能力的 ...
2025-07-04SQL Server 字符串截取转日期:解锁数据处理的关键技能 在数据处理与分析工作中,数据格式的规范性是保证后续分析准确性的基础 ...
2025-07-04CDA 数据分析师视角:从数据迷雾中探寻商业真相 在数字化浪潮席卷全球的今天,数据已成为企业决策的核心驱动力,CDA(Certifie ...
2025-07-04CDA 数据分析师:开启数据职业发展新征程 在数据成为核心生产要素的今天,数据分析师的职业价值愈发凸显。CDA(Certified D ...
2025-07-03从招聘要求看数据分析师的能力素养与职业发展 在数字化浪潮席卷全球的当下,数据已成为企业的核心资产,数据分析师岗位也随 ...
2025-07-03Power BI 中如何控制过滤器选择项目数并在超限时报错 引言 在使用 Power BI 进行数据可视化和分析的过程中,对过滤器的有 ...
2025-07-03把握 CDA 考试时间,开启数据分析职业之路 在数字化转型的时代浪潮下,数据已成为企业决策的核心驱动力。CDA(Certified Da ...
2025-07-02CDA 证书:银行招聘中的 “黄金通行证” 在金融科技飞速发展的当下,银行正加速向数字化、智能化转型,海量数据成为银行精准 ...
2025-07-02探索最优回归方程:数据背后的精准预测密码 在数据分析和统计学的广阔领域中,回归分析是揭示变量之间关系的重要工具,而回 ...
2025-07-02CDA 数据分析师报考条件全解析:开启数据洞察之旅 在当今数字化浪潮席卷全球的时代,数据已成为企业乃至整个社会发展的核心驱 ...
2025-07-01深入解析 SQL 中 CASE 语句条件的执行顺序 在 SQL 编程领域,CASE语句是实现条件逻辑判断、数据转换与分类的重要工 ...
2025-07-01SPSS 中计算三个变量交集的详细指南 在数据分析领域,挖掘变量之间的潜在关系是获取有价值信息的关键步骤。当我们需要探究 ...
2025-07-01CDA 数据分析师:就业前景广阔的新兴职业 在当今数字化时代,数据已成为企业和组织决策的重要依据。数据分析师作为负责收集 ...
2025-06-30探秘卷积层:为何一个卷积层需要两个卷积核 在深度学习的世界里,卷积神经网络(CNN)凭借其强大的特征提取能力 ...
2025-06-30探索 CDA 数据分析师在线课程:开启数据洞察之旅 在数字化浪潮席卷全球的当下,数据已成为企业决策、创新与发展的核心驱 ...
2025-06-303D VLA新范式!CVPR冠军方案BridgeVLA,真机性能提升32% 编辑:LRST 【新智元导读】中科院自动化所提出BridgeVLA模型,通过将 ...
2025-06-30LSTM 为何会产生误差?深入剖析其背后的原因 在深度学习领域,LSTM(Long Short-Term Memory)网络凭借其独特的记忆单元设 ...
2025-06-27LLM进入拖拽时代!只靠Prompt几秒定制大模型,效率飙升12000倍 【新智元导读】最近,来自NUS、UT Austin等机构的研究人员创新 ...
2025-06-27探秘 z-score:数据分析中的标准化利器 在数据的海洋中,面对形态各异、尺度不同的数据,如何找到一个通用的标准来衡量数据 ...
2025-06-26Excel 中为不同柱形设置独立背景(按数据分区)的方法详解 在数据分析与可视化呈现过程中,Excel 柱形图是展示数据的常用工 ...
2025-06-26