编写 Python 程序,读取一个 24 位真彩色 BMP 文件(已提供 素材),然后转化为灰色图像,最后存储为 8 位伪彩色 BMP 文 件;,要求使用面向对象的方 式来写(使用 class),不能使用 Python 图像模块/包/库,如 opencv、 PIL 等。在定义 class 里的成员时,可使用 int.to_bytes、int.from_bytes 等
时间: 2024-03-16 12:46:51 浏览: 40
好的,我会按照你的要求,使用面向对象的方式来实现这个程序,并且不使用任何图像处理模块或库。这个程序主要包括以下几个步骤:
1.读取BMP文件的文件头和信息头,并解析出图像的宽度、高度和像素点的位数。
2.读取像素点的值,并转换为灰度值。
3.将灰度值转换为8位伪彩色并存储为BMP文件。
下面是完整的代码:
```python
class BMPConverter:
def __init__(self, filename):
self.filename = filename
self.width = 0
self.height = 0
self.bitcount = 0
self.pixels = []
def read_file_header(self, f):
# 读取文件头
f.seek(0)
bfType = f.read(2)
bfSize = int.from_bytes(f.read(4), byteorder='little')
bfReserved1 = int.from_bytes(f.read(2), byteorder='little')
bfReserved2 = int.from_bytes(f.read(2), byteorder='little')
bfOffBits = int.from_bytes(f.read(4), byteorder='little')
def read_info_header(self, f):
# 读取信息头
f.seek(14)
biSize = int.from_bytes(f.read(4), byteorder='little')
biWidth = int.from_bytes(f.read(4), byteorder='little')
biHeight = int.from_bytes(f.read(4), byteorder='little')
biPlanes = int.from_bytes(f.read(2), byteorder='little')
biBitCount = int.from_bytes(f.read(2), byteorder='little')
biCompression = int.from_bytes(f.read(4), byteorder='little')
biSizeImage = int.from_bytes(f.read(4), byteorder='little')
biXPelsPerMeter = int.from_bytes(f.read(4), byteorder='little')
biYPelsPerMeter = int.from_bytes(f.read(4), byteorder='little')
biClrUsed = int.from_bytes(f.read(4), byteorder='little')
biClrImportant = int.from_bytes(f.read(4), byteorder='little')
self.width = biWidth
self.height = biHeight
self.bitcount = biBitCount
def read_pixels(self, f):
# 读取像素点
f.seek(54)
for i in range(self.height):
row = []
for j in range(self.width):
b = int.from_bytes(f.read(1), byteorder='little')
g = int.from_bytes(f.read(1), byteorder='little')
r = int.from_bytes(f.read(1), byteorder='little')
gray = int(0.299 * r + 0.587 * g + 0.114 * b) # 转换为灰度值
row.append(gray)
self.pixels.append(row)
def convert_to_pseudocolor(self):
# 转换为8位伪彩色
palette = [(i, i, i) for i in range(256)]
new_pixels = []
for row in self.pixels:
new_row = []
for pixel in row:
new_row.append(pixel)
new_pixels.append(new_row)
bmp_data = []
for row in new_pixels:
for pixel in row:
bmp_data.append(pixel)
# 添加调色板信息
palette_data = []
for color in palette:
palette_data += color
# 写入BMP文件
with open('pseudo.bmp', 'wb') as f:
# 写入文件头
f.write(b'BM')
f.write((54 + len(palette_data) + len(bmp_data)).to_bytes(4, byteorder='little'))
f.write(b'\x00\x00')
f.write(b'\x00\x00')
f.write((54 + len(palette_data)).to_bytes(4, byteorder='little'))
# 写入信息头
f.write(b'\x28\x00\x00\x00')
f.write(self.width.to_bytes(4, byteorder='little'))
f.write(self.height.to_bytes(4, byteorder='little'))
f.write(b'\x01\x00')
f.write(b'\x08\x00')
f.write(b'\x00\x00\x00\x00')
f.write(len(bmp_data).to_bytes(4, byteorder='little'))
f.write(b'\x00\x00\x00\x00')
f.write(b'\x00\x00\x00\x00')
f.write(b'\x00\x00\x00\x00')
f.write(b'\x00\x00\x00\x00')
f.write(b'\x00\x00\x00\x00')
# 写入调色板信息
f.write(bytes(palette_data))
# 写入像素点信息
f.write(bytes(bmp_data))
def convert(self):
with open(self.filename, 'rb') as f:
self.read_file_header(f)
self.read_info_header(f)
self.read_pixels(f)
self.convert_to_pseudocolor()
if __name__ == '__main__':
converter = BMPConverter('24bit.bmp')
converter.convert()
```
在这个程序中,我们定义了一个名为`BMPConverter`的类,它包含了读取BMP文件、转换为灰度图像、转换为8位伪彩色图像和存储为BMP文件等方法。这个类的主要流程是先读取BMP文件的文件头和信息头,然后读取像素点的值,并转换为灰度值,最后将灰度值转换为8位伪彩色并存储为BMP文件。
注意,最后的`if __name__ == '__main__':`语句是为了让这个程序在被引用时不会自动执行,只有在直接运行这个程序时才会执行。