实验题目:设计和实现24位位图图片色彩翻转成互补色程序。
(提示:24位位图文件中的数据部分定义了每上像素像素单元,每个像素由三个字节组成,分别表示红、绿、蓝(r,g,b)三个分量,假设设这三量分别是x,y,z,那么255-x,255-y,255-z就是它的互补色。)
解题思路与算法设计:
1、看书查找二进制文件的操作方法,包括:打开二进制文件,读或写二进制文件的方法。
2、查找网络资源,找出24彩色图片的格式(注意:彩色图片文件有多种,比如:16位彩色文件,32位彩色文件等等,不要搞错了!24位位图文件分三部分:文件信息头、图像信息头和图像像素数据),我们要搞清楚文件信息头的长度和每个字节的含义,图像信息头的长度和每个字节的含义和像素数据的格式。
3、准备图片,注意不要搞错了,如果找不到24位位图(.bmp)文件,可以用系统自带pant打开一个别的图片,再另存为24位位图文件。
4、编程实现:
(1)打开位图文件(原文件)读取文件信息头的关键信息以确认这个文件是24位位图文件。
(2)读取文件的像素信息头的关键信息,比如:确定像素的有多少行,一行有多少像素等信息。
(3)新建一个位图文件,扩展名是.bmp(目标文件),把原图像文件的信息头的信息全部拷贝过去。
(4)将原文件指针移动到像素数据起始处,循环读取每个像素的r,g,b值。再把255-r,
255-g,255-b的值写到目标文件中。值到处理完有像素为止。关闭所有文件。
(5)打开目标文件查看翻转后的图片,验证你的代码。
from struct import *
class rmb:
def __init__(self):
file = open('messi.bmp', 'rb')
self.bfType = file.read(2)
self.bfSize = file.read(4)
self.bfReserved1 = file.read(2)
self.bfReserved2 = file.read(2)
self.bfOffBits = file.read(4)
self.biSize = file.read(4)
self.biWidth = file.read(4)
self.biHeight = file.read(4)
self.biPlanes = file.read(2)
self.biBitCount = file.read(2)
self.biCompression = file.read(4)
self.biSizeImage = file.read(4)
self.biXPelsPerMeter = file.read(4)
self.biYPelsPerMeter = file.read(4)
self.biClrUsed = file.read(4)
self.biClrImportant = file.read(4)
self.bmp_data = []
self.h, = unpack("<i", self.biHeight)
self.w, = unpack("<i", self.biWidth)
print(self.h)
print(self.w)
for height in range(self.h):
bmp_data_row = []
count = 0
for width in range(self.w):
bmp_data_row.append(
[unpack("<B", file.read(1))[0], unpack("<B", file.read(1))[0], unpack("<B", file.read(1))[0]])
count += 3
while count % 4 != 0:
file.read(1)
count += 1
self.bmp_data.append(bmp_data_row)
# self.bmp_data.reverse()
file.close()
def write_(self):
res_file = open('res.bmp', 'wb')
res_file.write(self.bfType)
res_file.write(self.bfSize)
res_file.write(self.bfReserved1)
res_file.write(self.bfReserved2)
res_file.write(self.bfOffBits)
res_file.write(self.biSize)
res_file.write(self.biWidth)
res_file.write(self.biHeight)
res_file.write(self.biPlanes)
res_file.write(self.biBitCount)
res_file.write(self.biCompression)
res_file.write(self.biSizeImage)
res_file.write(self.biXPelsPerMeter)
res_file.write(self.biYPelsPerMeter)
res_file.write(self.biClrUsed)
res_file.write(self.biClrImportant)
# res_file.write(bytes(self.img))
for height in range(self.h):
bmp_data_row = self.bmp_data[height]
count = 0
for width in range(self.w):
res_file.write(pack("<B", 255 - bmp_data_row[width][0]))
res_file.write(pack("<B", 255 - bmp_data_row[width][1]))
res_file.write(pack("<B", 255 - bmp_data_row[width][2]))
count += 3
while count % 4 != 0:
res_file.write(pack("<B", 0))
count += 1
res = rmb
res.__init__(self=res)
res.write_(self=res)