基本方式完成

This commit is contained in:
Luthics 2023-01-06 22:43:06 +08:00
parent 1e5dd46c26
commit dccbbba5b0
10 changed files with 179 additions and 0 deletions

3
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,3 @@
{
"python.formatting.provider": "yapf"
}

BIN
imgs/16.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 B

BIN
imgs/16x16.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 822 B

BIN
imgs/24.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 B

BIN
imgs/256.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
imgs/4x4.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 B

BIN
imgs/bw.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 B

BIN
imgs/single.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 B

BIN
imgs/xjtu.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 270 KiB

176
main.py
View File

@ -0,0 +1,176 @@
from math import floor
# 十六进制转十进制
def byteSize(begin, length):
size = 0
for i in range(length):
size += imgBytes[i + begin] * 16**(2 * i)
return size
# 十进制转十六进制
def sizeByte(size, length):
b = []
while (size):
b.append(size // 16**((length - len(b) - 1) * 2))
size %= 16**((length - len(b)) * 2)
b.extend([0] * (length - len(b)))
return b[::-1]
# 输入数据
img = input("请输入图片路径:")
new_width = int(input("请输入新宽度(px)"))
new_height = int(input("请输入新高度(px)"))
# img = 'imgs/24.bmp'
# new_width = 128
# new_height = 128
# 读入图片
imgFile = open(img, 'rb')
imgBytes = imgFile.read()
# 文件头处理
# 检验文件头是否为 BM
if (imgBytes[0] != 66 or imgBytes[1] != 77):
print("当前文件非 BMP 格式")
exit()
fileSize = byteSize(2, 4) #文件头中的文件大小
dataStart = byteSize(10, 4) #文件头中的数据开始字节
# bmp 文件头
headerSize = byteSize(14, 4)
width = byteSize(18, 4)
height = byteSize(22, 4)
nbplan = byteSize(26, 2)
bpp = byteSize(28, 2)
compression = byteSize(30, 4)
imageSize = byteSize(34, 4)
# 调色板不做处理
# 变量预处理
pixels = []
for i in range(height):
pixels.append([])
rowLength = width
rowLength *= bpp // 8
while (rowLength % 4 != 0):
rowLength += 1
# 计算像素点
i = dataStart
currentRow = 0
while (currentRow < height):
currentCol = 0
while (currentCol < width * (bpp // 8)):
if (bpp == 32):
pixels[currentRow].append({
'r':
imgBytes[dataStart + currentRow * rowLength + currentCol],
'g':
imgBytes[dataStart + currentRow * rowLength + currentCol + 1],
'b':
imgBytes[dataStart + currentRow * rowLength + currentCol + 2],
'a':
imgBytes[dataStart + currentRow * rowLength + currentCol + 3]
})
currentCol += bpp // 8
else:
pixels[currentRow].append({
'r':
imgBytes[dataStart + currentRow * rowLength + currentCol],
'g':
imgBytes[dataStart + currentRow * rowLength + currentCol + 1],
'b':
imgBytes[dataStart + currentRow * rowLength + currentCol + 2]
})
currentCol += bpp // 8
currentRow += 1
# 读入图片为像素数组完成
# 缩放图片
# 变量预处理
scale_w = new_width / width
scale_h = new_height / height
newpixels = []
for i in range(new_height):
newpixels.append([])
# 计算新像素
currentRow = 0
while (currentRow < new_height):
currentCol = 0
while (currentCol < new_width):
newpixels[currentRow].append(pixels[floor(currentRow / scale_h)][floor(
currentCol // scale_w)])
currentCol += 1
currentRow += 1
# 处理新文件
newimgArray = [66, 77]
rowLength = new_width
rowLength *= bpp // 8
while (rowLength % 4 != 0):
rowLength += 1
# 新文件头
new_fileSize = 54 + rowLength * new_height #文件头中的文件大小
newimgArray.extend(sizeByte(new_fileSize, 4))
newimgArray.extend(sizeByte(0, 4))
new_dataStart = dataStart
newimgArray.extend(sizeByte(new_dataStart, 4))
# 新 bmp 文件头
new_headerSize = headerSize
newimgArray.extend(sizeByte(headerSize, 4))
new_width_b = sizeByte(new_width, 4)
newimgArray.extend(new_width_b)
new_height_b = sizeByte(new_height, 4)
newimgArray.extend(new_height_b)
new_nbplan = nbplan
newimgArray.extend(sizeByte(new_nbplan, 2))
new_bpp = bpp
newimgArray.extend(sizeByte(bpp, 2))
new_compression = compression
newimgArray.extend(sizeByte(new_compression, 4))
new_imageSize = rowLength * new_height
newimgArray.extend(sizeByte(new_imageSize, 4))
# 调色板不做处理
newimgArray.extend(sizeByte(0, new_headerSize + 14 - len(newimgArray)))
for i in range(len(newpixels)):
row = newpixels[i]
for col in range(len(row)):
if (new_bpp // 8 == 3):
pixel = [
newpixels[i][col]['r'], newpixels[i][col]['g'],
newpixels[i][col]['b']
]
else:
pixel = [
newpixels[i][col]['r'], newpixels[i][col]['g'],
newpixels[i][col]['b'], newpixels[i][col]['a']
]
newimgArray.extend(pixel)
newimgArray.extend(sizeByte(0, rowLength - len(row) * (new_bpp // 8)))
# 写入新的文件
newimgBytes = bytes(newimgArray)
with open(img[:-4] + "_new" + img[-4:], 'wb') as f:
f.write(newimgBytes)
# 关闭文件
imgFile.close()