diff --git a/imgs/1/1x3.bmp b/imgs/1/1x3.bmp deleted file mode 100644 index 0e43249..0000000 Binary files a/imgs/1/1x3.bmp and /dev/null differ diff --git a/imgs/1/2x1.bmp b/imgs/1/2x1.bmp deleted file mode 100644 index a76cdbc..0000000 Binary files a/imgs/1/2x1.bmp and /dev/null differ diff --git a/imgs/1/2x3.bmp b/imgs/1/2x3.bmp deleted file mode 100644 index 71fa073..0000000 Binary files a/imgs/1/2x3.bmp and /dev/null differ diff --git a/imgs/16.bmp b/imgs/16.bmp deleted file mode 100644 index 4c545ce..0000000 Binary files a/imgs/16.bmp and /dev/null differ diff --git a/imgs/2221.bmp b/imgs/2221.bmp new file mode 100644 index 0000000..31672e7 Binary files /dev/null and b/imgs/2221.bmp differ diff --git a/imgs/256.bmp b/imgs/256.bmp deleted file mode 100644 index 0d5bfeb..0000000 Binary files a/imgs/256.bmp and /dev/null differ diff --git a/main.py b/main.py index e8ef05b..ce43b15 100644 --- a/main.py +++ b/main.py @@ -1,21 +1,24 @@ -from math import floor +from math import floor, ceil from tqdm import tqdm ################## 数据输入 Start ################## # 输入数据 + # img = input("请输入图片路径:") # new_width = int(input("请输入新宽度(px):")) # new_height = int(input("请输入新高度(px):")) -# print("模式 0 直接缩放") -# print("模式 1 高斯模糊缩放") +# print("模式 0 双线性插值") +# print("模式 1 最邻近插值") +# print("模式 2 高斯模糊缩放") # mode = int(input("请输入模式:")) -img = 'imgs/1/2x1.bmp' -new_width = 512 -new_height = 512 -mode = 0 -if (mode != 1): +img = 'imgs/xjtu.bmp' +new_width = 256 +new_height = 256 +mode = 1 + +if (mode not in [0, 1, 2]): mode = 0 ################## 数据输入 End ################## @@ -86,7 +89,7 @@ while (i < len(colorsBoard)): }) i += 4 -if (not (bpp in [1, 2, 4, 8, 16, 24, 32])): +if (not (bpp in [24, 32])): print("不支持该图片") exit() ################## 文件头处理 End ################## @@ -102,10 +105,22 @@ rowLength = floor(width * bpp / 8) while (rowLength % 4 != 0 or rowLength == 0): rowLength += 1 +# colorsIndex = [] +# if (bpp == 1): +# initPixel = imgBytes[dataStart] // 128 +# colorsIndex.append() + # 计算像素点 i = dataStart for currentRow in tqdm(range(height), "读入像素点中"): currentCol = 0 + # if (bpp in [1, 2, 4, 8]): + # # 其实可以直接存入索引,之后再取出,但是为了易于理解,这里直接将像素数据插入 pixels 数组,这会导致效率的损失 + # b = 0 + # # while(b < width*bpp): + # # if(bpp==1): + # # print("") + # else: while (currentCol < width * (bpp // 8)): if (bpp == 32): pixels[currentRow].append({ @@ -126,7 +141,9 @@ for currentRow in tqdm(range(height), "读入像素点中"): 'g': imgBytes[dataStart + currentRow * rowLength + currentCol + 1], 'b': - imgBytes[dataStart + currentRow * rowLength + currentCol + 2] + imgBytes[dataStart + currentRow * rowLength + currentCol + 2], + 'a': + 0 }) currentCol += bpp // 8 # 读入图片为像素数组完成 @@ -139,12 +156,66 @@ newpixels = [] for i in range(new_height): newpixels.append([]) + +# 辅助计算函数 +def linear_single(x, x1, x2, f1, f2): + return floor(f1 * (x2 - x) / (x2 - x1) + f2 * (x - x1) / (x2 - x1)) + + +# 双线性插值函数 +# 参考 https://zh.wikipedia.org/wiki/%E5%8F%8C%E7%BA%BF%E6%80%A7%E6%8F%92%E5%80%BC +def linear_insert(row, col): + x = row / scale_h + y = col / scale_w + # 如果整数格点就直接返回 + x1 = floor(x) + x2 = ceil(x) + y1 = floor(y) + y2 = ceil(y) + if (x2 >= height): + x2 = x1 + if (y2 >= width): + y2 = y1 + if (x1 == x2 and y1 == y2): + return pixels[x1][y1] + if (x1 == x2): + x = x1 + r = linear_single(y, y1, y2, pixels[x][y1]['r'], pixels[x][y2]['r']) + g = linear_single(y, y1, y2, pixels[x][y1]['g'], pixels[x][y2]['g']) + b = linear_single(y, y1, y2, pixels[x][y1]['b'], pixels[x][y2]['b']) + a = linear_single(y, y1, y2, pixels[x][y1]['a'], pixels[x][y2]['a']) + return {'r': r, 'g': g, 'b': b, 'a': a} + if (y1 == y2): + y = y1 + r = linear_single(x, x1, x2, pixels[x1][y]['r'], pixels[x2][y]['r']) + g = linear_single(x, x1, x2, pixels[x1][y]['g'], pixels[x2][y]['g']) + b = linear_single(x, x1, x2, pixels[x1][y]['b'], pixels[x2][y]['b']) + a = linear_single(x, x1, x2, pixels[x1][y]['a'], pixels[x2][y]['a']) + return {'r': r, 'g': g, 'b': b, 'a': a} + fy1_r = linear_single(x, x1, x2, pixels[x1][y1]['r'], pixels[x2][y1]['r']) + fy1_g = linear_single(x, x1, x2, pixels[x1][y1]['g'], pixels[x2][y1]['g']) + fy1_b = linear_single(x, x1, x2, pixels[x1][y1]['b'], pixels[x2][y1]['b']) + fy1_a = linear_single(x, x1, x2, pixels[x1][y1]['a'], pixels[x2][y1]['a']) + fy2_r = linear_single(x, x1, x2, pixels[x1][y2]['r'], pixels[x2][y2]['r']) + fy2_g = linear_single(x, x1, x2, pixels[x1][y2]['g'], pixels[x2][y2]['g']) + fy2_b = linear_single(x, x1, x2, pixels[x1][y2]['b'], pixels[x2][y2]['b']) + fy2_a = linear_single(x, x1, x2, pixels[x1][y2]['a'], pixels[x2][y2]['a']) + r = linear_single(y, y1, y2, fy1_r, fy2_r) + g = linear_single(y, y1, y2, fy1_g, fy2_g) + b = linear_single(y, y1, y2, fy1_b, fy2_b) + a = linear_single(y, y1, y2, fy1_a, fy2_a) + return {'r': r, 'g': g, 'b': b, 'a': a} + + # 计算新像素 for currentRow in tqdm(range(new_height), "计算新像素点中"): for currentCol in range(new_width): - ori_row = floor(currentRow / scale_h) - ori_col = floor(currentCol // scale_w) - newpixels[currentRow].append(pixels[ori_row][ori_col]) + if (mode == 0): + newpixels[currentRow].append(linear_insert(currentRow, currentCol)) + elif (mode == 1): + ori_row = floor(currentRow / scale_h) + ori_col = floor(currentCol / scale_w) + newpixels[currentRow].append(pixels[ori_row][ori_col]) # 处理新文件 newimgArray = [66, 77] @@ -185,8 +256,21 @@ 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))) +new_wppm = wppm +newimgArray.extend(sizeByte(new_wppm, 4)) + +new_hppm = hppm +newimgArray.extend(sizeByte(new_hppm, 4)) + +new_colorsNum = colorsNum +newimgArray.extend(sizeByte(new_colorsNum, 4)) + +new_icolorsNum = icolorsNum +newimgArray.extend(sizeByte(new_icolorsNum, 4)) + +new_colorsBoard = colorsBoard +for color in new_colorsBoard: + newimgArray.append(color) def flur(row, col): @@ -244,7 +328,9 @@ def flur(row, col): for i in tqdm(range(len(newpixels)), "将像素点格式化中"): row = newpixels[i] for col in range(len(row)): - if (mode == 0): + if (mode == 2): + newimgArray.extend(flur(i, col)) + else: if (new_bpp // 8 == 3): pixel = [ newpixels[i][col]['r'], newpixels[i][col]['g'], @@ -256,14 +342,12 @@ for i in tqdm(range(len(newpixels)), "将像素点格式化中"): newpixels[i][col]['b'], newpixels[i][col]['a'] ] newimgArray.extend(pixel) - elif (mode == 1): - newimgArray.extend(flur(i, col)) newimgArray.extend(sizeByte(0, rowLength - len(row) * (new_bpp // 8))) # 写入新的文件 newimgBytes = bytes(newimgArray) -with open(img[:-4] + "_new" + img[-4:], 'wb') as f: +with open(img[:-4] + "_" + str(mode) +"_new" + img[-4:], 'wb') as f: f.write(newimgBytes) for _ in tqdm(range(len(newimgBytes)), "写出图片中"): pass \ No newline at end of file