介绍

由于要开始学习图像方面的知识,读写图片是难免的。对图片的结构有一定的了解对理解图片存储还是很有帮助的。由于实验的代码是用 python 写的,因此读取文件就直接使用 python 了,虽然用 C 来读写文件更有效率,但我个人感觉 python 也没有很慢。下面来看一下bmp 文件结构和读取 bmp 文件的过程。

bmp 文件结构

  • bmp文件头(bmp file header):提供文件的格式、大小等信息

  • 位图信息头(bitmap information):提供图像数据的尺寸、位平面数、压缩方式、颜色索引等信息

  • 调色板(color palette):可选,如使用索引来表示图像,调色板就是索引与其对应的颜色的映射表

  • 位图数据(bitmap data):就是图像数据

用表格形式可以表示为:

首先来看文件头的信息(14字节):

然后是位图信息图(40字节):

一般情况下,到这里我们就可以得到这个图片的基本信息了。由于调色板是不确定的,而且现在的bmp图片一般都没有调色板信息(因为24位),所以忽略第三个。

所以,思路还是很简单的。先读取 54 字节的头文件,利用读取的图片宽和高信息,对后面的数据进行读取。

注意:由于是以二进制形式进行读取的,因此,需要注意存储方式。bmp 文件的存储方式是小端方式,读取的时候也要使用小端法进行解析

Python 代码

# -*- coding: UTF-8 -*-
from struct import unpack# 读取并存储 bmp 文件
class ReadBMPFile :def __init__(self, filePath) :file = open(filePath, "rb")# 读取 bmp 文件的文件头    14 字节self.bfType = unpack("<h", file.read(2))[0]       # 0x4d42 对应BM 表示这是Windows支持的位图格式self.bfSize = unpack("<i", file.read(4))[0]       # 位图文件大小self.bfReserved1 = unpack("<h", file.read(2))[0]  # 保留字段 必须设为 0 self.bfReserved2 = unpack("<h", file.read(2))[0]  # 保留字段 必须设为 0 self.bfOffBits = unpack("<i", file.read(4))[0]    # 偏移量 从文件头到位图数据需偏移多少字节(位图信息头、调色板长度等不是固定的,这时就需要这个参数了)# 读取 bmp 文件的位图信息头 40 字节self.biSize = unpack("<i", file.read(4))[0]       # 所需要的字节数self.biWidth = unpack("<i", file.read(4))[0]      # 图像的宽度 单位 像素self.biHeight = unpack("<i", file.read(4))[0]     # 图像的高度 单位 像素self.biPlanes = unpack("<h", file.read(2))[0]     # 说明颜色平面数 总设为 1self.biBitCount = unpack("<h", file.read(2))[0]   # 说明比特数self.biCompression = unpack("<i", file.read(4))[0]  # 图像压缩的数据类型self.biSizeImage = unpack("<i", file.read(4))[0]    # 图像大小self.biXPelsPerMeter = unpack("<i", file.read(4))[0]# 水平分辨率self.biYPelsPerMeter = unpack("<i", file.read(4))[0]# 垂直分辨率self.biClrUsed = unpack("<i", file.read(4))[0]      # 实际使用的彩色表中的颜色索引数self.biClrImportant = unpack("<i", file.read(4))[0] # 对图像显示有重要影响的颜色索引的数目self.bmp_data = []if self.biBitCount != 24 :print("输入的图片比特值为 :" + str(self.biBitCount) + "\t 与程序不匹配")for height in range(self.biHeight) :bmp_data_row = []# 四字节填充位检测count = 0for width in range(self.biWidth) :bmp_data_row.append([unpack("<B", file.read(1))[0], unpack("<B", file.read(1))[0], unpack("<B", file.read(1))[0]])count = count + 3# bmp 四字节对齐原则while count % 4 != 0 :file.read(1)count = count + 1self.bmp_data.append(bmp_data_row)self.bmp_data.reverse()file.close()# R, G, B 三个通道self.R = []self.G = []self.B = []for row in range(self.biHeight) :R_row = []G_row = []B_row = []for col in range(self.biWidth) :B_row.append(self.bmp_data[row][col][0])G_row.append(self.bmp_data[row][col][1])R_row.append(self.bmp_data[row][col][2])self.B.append(B_row)self.G.append(G_row)self.R.append(R_row)

这里,读取完文件后,我又将 R、G、B 三个通道的数值分出来了。主要是为了方便后续的处理,毕竟读取文件的目的是为了后面对图像的处理。

这是一个类,外部代码可以这样调用:

import numpy as np
import sys
from ReadBMPFile import ReadBMPFile
import cv2
# 命令行传入的文件路径
filePath = sys.argv[1]
# 读取 BMP 文件
bmpFile = ReadBMPFile(filePath)
# R, G, B 三个通道 [0, 255]
R = bmpFile.R
G = bmpFile.G
B = bmpFile.B
# 显示图像
b = np.array(B, dtype = np.uint8)
g = np.array(G, dtype = np.uint8)
r = np.array(R, dtype = np.uint8)
merged = cv2.merge([b, g, r]) #合并R、G、B分量 默认顺序为 B、G、R
cv2.imshow("Merged",merged)

参考文献

  1. BMP文件格式详解(BMP fileformat)
  2. 简单bmp图片处理工具——python实现

Python读取并解析 bmp 文件相关推荐

  1. python读取xml_python解析xml文件

    加载和读取xml文件 import xml.dom.minidom doc = xml.dom.minidom.parse(xmlfile) 获取xml文档对象(对子节点和节点node都适用) roo ...

  2. Python读取多个excel文件(删除字段、数据格式转换、dataframe多表合并)并写入ElasticSearch实战(自动创建索引、写入ElasticSearch、探索性数据分析)

    Python读取多个excel文件(删除字段.数据格式转换.dataframe多表合并)并写入ElasticSearch实战(自动创建索引.写入ElasticSearch.探索性数据分析) 目录

  3. python读取txt文件写入-python 读取、写入txt文件的示例

    写入文件 使用open()函数和write()函数 但是有两种写法,分别是'a'和'w' 'a' 表示写入文件 若无该文件会直接创建一个 如果存在这个文件,会接着已有的内容的后面写入 with ope ...

  4. python分析pcap文件_利用Python库Scapy解析pcap文件的方法

    每次写博客都是源于纳闷,python解析pcap这么常用的例子网上竟然没有,全是一堆命令行执行的python,能用吗?玩呢? pip安装scapy,然后解析pcap: import scapy fro ...

  5. jq ajax xml,jQuery+ajax读取并解析XML文件的方法

    本文实例讲述了jQuery+ajax读取并解析XML文件的方法.分享给大家供大家参考,具体如下: ajax.xml: zhangsan 1 lisi 2 demo.html: /p> " ...

  6. python shp文件_对python 读取线的shp文件实例详解

    如下所示: import shapefile sf = shapefile.reader("e:\\1.2\\cs\\dx_csl.shp") shapes = sf.shapes ...

  7. 使用Python读取LabVIEW TDMS 格式文件转成Excel格式+多进程版本

    使用Python读取LabVIEW TDMS 格式文件转成Excel格式+多进程版本 文章目录 使用Python读取LabVIEW TDMS 格式文件转成Excel格式+多进程版本 前言: 背景 tm ...

  8. Java I/O读取和解析.emp文件示例

    Java I/O读取和解析.emp文件示例 1.使用到的知识点 2.示例1 2.1存储几个员工数据到不同的文件 2.1.1题目要求 2.1.2相关代码 2.1.3结果展示 2.2读取存储数据的文件 2 ...

  9. Python读取.dat后缀名文件

    Python读取.dat后缀名文件 .dat文件基本上是没有任何头的二进制文件.对于每个样本,它由(256,256,3)个uint8图像,(64,64,1)uint8深度图和1个uint8标签组成.T ...

最新文章

  1. 谈谈JQuery的Deferred对象
  2. python csv 中文乱码_python读写csv时中文乱码问题解决办法
  3. idea2020shezhi代码检查级别_优秀的模糊测试代码是如何炼成的?
  4. Nginx实现负载均衡(整合SpringBoot小demo)
  5. 21 FI配置-财务会计-为非征税事务分配税务代码
  6. mysql 状态机_动画状态机(2)
  7. HAproxy负载均衡动静分离实现及配置详解
  8. 最新老韩泰牛PHP基础班+大牛班+大牛班高级课程
  9. DAMS峰会丨从数仓到数据中台,从数据资源到资产,京东、携程、快手等是怎么建设和演进的?...
  10. 新元宇宙每周连载《地球人奇游天球记》第十七回海王会龙
  11. CL210管理存储--对象存储
  12. 解决高度塌陷的几种方法
  13. Three.js学习七——播放模型动画时模型沿着轨迹移动
  14. VS2008向工具箱中添加控件解决 未能实例化 设计时授权
  15. 0703齐次方程-微分方程
  16. 学人工智能有前途吗?AI发展前景怎么样?
  17. SSL 2344 洛谷 2835 信息学奥赛一本通 1383 刻录光盘#floyd,tarjan,kosaraju#
  18. matlab2014启动很慢,[转载]matlab启动慢的解决方法
  19. Herrig Schiefspiegler望远镜
  20. linux启动jar后运行其他命令,Linux 部署jar 后台持续运行

热门文章

  1. 越来越多“大龄”考生重返校园?百度“2021考研”大数据
  2. HTTPS免费证书的申请与配置
  3. CAD 二次开发之创建包含文字的线型
  4. 02 Confluent_Kafka权威指南 第二章:安装kafka
  5. TFD on Desk V01.04(V01.42)丰田那智仿真离线软件
  6. 勾股定理一日一证连载123
  7. 微信好友列表数据结构分析
  8. Chrome商店镜像,支持各种插件下载
  9. 知乎话题1——计算机学生在大学如何学习
  10. 代理IP的使用以及正则表达式