加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

Python读取图片属性信息的实现方法

发布时间:2020-12-16 20:25:07 所属栏目:Python 来源:网络整理
导读:本文是利用Python脚本读取图片信息,有几个说明如下: 1、没有实现错误处理 2、没有读取所有信息,大概只有 GPS 信息、图片分辨率、图片像素、设备商、拍摄设备等 3、简单修改后应该能实现暴力修改图片的 GPS 信息 4、但对于本身没有 GPS 信息的图片,实现则

本文是利用Python脚本读取图片信息,有几个说明如下:

     1、没有实现错误处理

     2、没有读取所有信息,大概只有 GPS 信息、图片分辨率、图片像素、设备商、拍摄设备等

     3、简单修改后应该能实现暴力修改图片的 GPS 信息

     4、但对于本身没有 GPS 信息的图片,实现则非常复杂,需要仔细计算每个描述符的偏移量

脚本运行后,读取结果如下


脚本读取的信息

这里和 Windows 属性查看器读到的内容完全一致


图片信息1


图片信息2

源码如下

# -*- coding:utf-8 -*-
import binascii

class ParseMethod(object):
  @staticmethod
  def parse_default(f,count,offset):
    pass

  @staticmethod
  def parse_latitude(f,offset):
    old_pos = f.tell()
    f.seek(12 + offset)

    latitude = [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,offset):

    old_pos = f.tell()
    f.seek(12 + offset)

    longtitude = [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)


    print 'Longtitude:t%.2f %.2f' %.2f"' % (longtitude[0],longtitude[1],longtitude[2])
    f.seek(old_pos) 

  @staticmethod
  def parse_make(f,offset):
    old_pos = f.tell()
    f.seek(12 + offset)
    byte = f.read(count)
    a = byte.encode('hex')
    print 'Make:tt' + binascii.a2b_hex(a)
    f.seek(old_pos) 

  @staticmethod
  def parse_model(f,offset):
    old_pos = f.tell()
    f.seek(12 + offset)
    byte = f.read(count)
    a = byte.encode('hex')
    print 'Model:tt' + binascii.a2b_hex(a)
    f.seek(old_pos)     

  @staticmethod
  def parse_datetime(f,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,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,16)

    print 'YResolution:t' + str(xre) + ' dpi'
    f.seek(old_pos)

  @staticmethod
  def parse_exif_ifd(f,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,value_offset)

    f.seek(old_pos)  

  @staticmethod
  def parse_x_pixel(f,value):
    print 'X Pixels:t' + str(value)

  @staticmethod
  def parse_y_pixel(f,value):
    print 'y Pixels:t' + str(value)

  @staticmethod
  def parse_gps_ifd(f,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(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,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:tt' + 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:tt' + 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,value_offset)


  print
  print 'Finish print 0th IFD....'

总结

利用Python读取图片属性信息的实现方法到这就基本结束了,大家都学会了吗?希望这篇文章对大家的学习或者工作带来一定的帮助,

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读