python中提取位图信息(AttributeError: module 'struct' has no attribute 'unstack')

前言

今天这篇博文有点意思,它是从一个例子出发,从而体现出在编程中的种种细节和一些知识点的运用。和从前一样,我是人,离成神还有几十万里,所以无可避免的出现不严谨的地方甚至错误,请酌情阅读。


0x00

首先,题目是:读取一个位图文件(xxx.bmp),然后读取前30个字节,从这前三十个字节中提取一些信息。

这里有一些知识要先知道:一个位图的前30位有什么?

BMP格式采用小端方式存储数据,文件头的结构按顺序如下:

  • 前两个字节:‘BM‘表示Windows位图,‘BA‘表示OS/2位图;
  • 一个4字节整数:表示位图大小;
  • 一个4字节整数:保留位,始终为0;
  • 一个4字节整数:实际图像的偏移量;
  • 一个4字节整数:Header的字节数;
  • 一个4字节整数:图像宽度;
  • 一个4字节整数:图像高度;
  • 一个2字节整数:始终为1;
  • 一个2字节整数:颜色数。

你先要知道,读取一个位图的前30位,那么这前30位是什么编码呢?例如,某个位图的前30位:

 b‘\x42\x4d\x38\x8c\x0a\x00\x00\x00\x00\x00\x36\x00\x00\x00\x28\x00\x00\x00\x80\x02\x00\x00\x68\x01\x00\x00\x01\x00\x18\x00‘

很容易看出,它们的单位是bytes,也就是说,我们无法直接看懂它们,因此,我们得把它转换成我们能看懂的东西。

python有趣的地方就在这里了,Python提供了一个struct模块来解决bytes和数据类型的转换。

例如,我想把一个整数10241024转换为以bytes为单位的字节怎么办?(如果你不懂字节编码,看这里)很简单:

>>> struct.pack(‘>I‘, 10241024)
b‘\x00\x9cD\x00‘

稍微解释一下:

>表示字节顺序是big-endian,也就是网络序,I表示4字节无符号整数。



那么我想把以bytes为单位的字节转换回整型怎么办?,也很简单:

>>> struct.unpack(‘>I‘, b‘\x00\x9cD\x00‘)
(10241024,)

要注意的地方就是unpack函数的第一个参数:‘>I‘,解释和pack函数的一样。


0x01

到了这里,基本可以看例子了。说明:

  1. 我的执行环境是:python 3.6;
  2. data.bmp是我用Windows自带画图随手画的一个位图图片;
  3. 我把这个程序保存为:struct1.py;
  4. data.bmpstruct1.py同在一个Windows目录下,完整路径:G:\newpython\data.bmpG:\newpython\struct1.py

例子:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
import struct
from collections import namedtuple

def bmg_info(weitu):
    with open(weitu, ‘rb‘) as f:
        data = f.read(30)
    info = BMGinfo(*struct.unpack(‘<ccIIIIIIHH‘, data))
    if info.ch1 == b‘B‘ and (info.ch2 == b‘M‘ or info.ch2 == b‘A‘):
        return {
        ‘width‘: info.width,
        ‘height‘: info.height,
        ‘color‘: info.colornum
        }
    return None

if __name__ == "__main__":
    BMGinfo = namedtuple(‘BMGinfo‘, (‘ch1‘,‘ch2‘,‘size‘,‘reserved‘,‘offset‘,‘headerbits‘,‘width‘,‘height‘,‘num‘,‘colornum‘))
    weitu = sys.argv[1]
    print(bmg_info(weitu))

打开cmd,进入目录G:\newpython,执行命令:python struct1.py "G:\newpython\data.bmp"即可看见惊喜。

这篇博客说到这里,终于到了重要的地方。其实在实践这段代码时,我遇见了几个问题(错误):

  1. 遇到错误(AttributeError: module ‘struct‘ has no attribute ‘unpack‘),原来是我自己的py文件不要和系统的模块名重名,解决办法,把文件名改掉(我这里把struct.py改为struct1.py);
  2. 灵活运用namedtuple。了解更多请看这里
  3. 灵活运用可变参数技能(*struct.unpack(‘<ccIIIIIIHH‘, data)),关于可变参数,看这里

0x10

感谢阅读。

python中提取位图信息(AttributeError: module 'struct' has no attribute 'unstack')

原文地址:https://www.cnblogs.com/busui/p/9351772.html

时间: 2024-10-20 05:50:16

python中提取位图信息(AttributeError: module 'struct' has no attribute 'unstack')的相关文章

【Python 脚本报错】AttributeError: &#39;module &#39;yyy&#39; has no attribute &#39;xxx&#39;的解决方法

先参考这篇记录大概理解了原因, 再深入了解下python的import机制, 发现自己的模块之间存在互相import. 比如,A.py中import B,而B.py中也import A了, 现在执行模块A,就会先将B中的代码搬过来,但B中有import A,而此时A.pyc还没生成,所以B中import A之后的代码也执行不了: 如果mode B 的 attribute xxx是定义在import A之后,那么就会出现题目中的报错: (而python是解释性语言,所以import A之前的代码还

python中引入包的时候报错AttributeError: module &#39;sys&#39; has no attribute &#39;setdefaultencoding&#39;解决方法?

python中引入包的时候报错:import unittestimport smtplibimport timeimport osimport sysimp.reload(sys)sys.setdefaultencoding('utf-8') AttributeError: module 'sys' has no attribute 'setdefaultencoding'解决方法: 1.python2中解决方法:reload(sys)sys.setdefaultencoding('utf-8'

python进阶四(类的继承)【4-5 python中获取对象信息】

python中获取对象信息 拿到一个变量,除了用 isinstance() 判断它是否是某种类型的实例外,还有没有别的方法获取到更多的信息呢? 例如,已有定义: 1 class Person(object): 2 def __init__(self, name, gender): 3 self.name = name 4 self.gender = gender 5 6 class Student(Person): 7 def __init__(self, name, gender, score

Python脚本报错AttributeError: ‘module’ object has no attribute’xxx’解决方法

最近在编写Python脚本过程中遇到一个问题比较奇怪:Python脚本完全正常没问题,但执行总报错"AttributeError: 'module' object has no attribute 'xxx'".这其实是.pyc文件存在问题. 问题定位: 查看import库的源文件,发现源文件存在且没有错误,同时存在源文件的.pyc文件 问题解决方法: 1. 命名py脚本时,不要与python预留字,模块名等相同 2. 删除该库的.pyc文件(因为py脚本每次运行时均会生成.pyc文件

[Python]attributeError:&#39;module&#39; object has no attribute &#39;dump&#39;

[问题] [代码] 文件名:pickle.py # coding=utf-8 #持久存储 import pickle #b 以二进制的模式打开文件 with open('mydata.pickle','wb') as mysavedata: #用dump保存数据 pickle.dump([1,2,'three'],mysavedata) #b 以二进制的模式打开文件 with open('mydata.pickle','rb') as myreaddata: #使用load恢复数据 list =

AttributeError: &#39;module&#39; object has no attribute &#39;handlers&#39;--Python子模块导入问题

想使用python的logging模块记录日志,并使用RotatingFileHandler来处理日志以便于在日志文件超过指定的大小后会重新生成新的日志文件. 基本代码如下: import logging logger = logging.getLogger('mylogger') logger.setLevel(logging.INFO) fh=logging.handlers.RotatingFileHandler('/tmp/test.log', mode = 'a', maxBytes=

从MP3中提取歌曲信息

一首MP3歌曲除了音乐信息外,还包含了如歌名.演唱者等信息,当我们用winamp软件听音乐时,播放清单就自动将这些信息读出来.大部分人都喜欢从网上下载音乐,但下载下来的MP3文件名都是文件上传系统自动取名的,和歌曲本身根本不相符,所以,给用户带来了很大的麻烦.但是,懒人有懒人的做法,我们何不自己写一个程序,将歌曲信息自动读出来并为MP3文件自动更名呢? 下面我就以C#为工具,把开发过程写出来. 一首MP3的额外信息存放在文件的最后面,共占128个字节,其中包括以下的内容(我们定义一个结构说明):

python 脚本运行时报错: AttributeError: &#39;module&#39; object has no attribute ***

最近在编写Python脚本过程中遇到一个问题比较奇怪:Python脚本完全正常没问题,但执行总报错"AttributeError: 'module' object has no attribute 'xxx'".这其实是.pyc文件存在问题. 问题定位: 查看import库的源文件,发现源文件存在且没有错误,同时存在源文件的.pyc文件 问题解决方法: 1. 命名py脚本时,不要与python预留字,模块名等相同 2. 删除该库的.pyc文件(因为py脚本每次运行时均会生成.pyc文件

Python报错“AttributeError: module &#39;sys&#39; has no attribute &#39;setdefaultencoding&#39;问题”

Python3中写法: import imp import sys imp.reload(sys) Python2中写法: import sys reload(sys) sys.setdefaultencoding("utf-8") Python报错"AttributeError: module 'sys' has no attribute 'setdefaultencoding'问题" 原文地址:https://www.cnblogs.com/yznmj-112/