文章目录
- 说明:
- 合并图片的三个过程
- 1、参考原博主的:
- 2、优化第一个数量问题:
- 3、优化俩个问题(数量不限+性状按比例变小)
- 4、优化黑行高度问题
- 5、合成图片不清晰问题:
- 总结下:
说明:
今天想着把图片如何合并成一张图片,然后我就搜到了一篇博客,博主写的很好,我仔细看了,还能用,就是效果不太好(就是原图的形状比例变了,看着很不爽),然后我重新优化了下。
合并图片的三个过程
1、参考原博主的:
参考博文地址
import osimport PIL.Image as ImageIMAGES_PATH = r'E:\000photo\漫画柜\\' # 图片集地址
IMAGES_FORMAT = ['.jpg', '.JPG'] # 图片格式
IMAGE_SIZE = 256 # 每张小图片的大小
IMAGE_ROW = 4 # 图片间隔,也就是合并成一张图后,一共有几行
IMAGE_COLUMN = 6 # 图片间隔,也就是合并成一张图后,一共有几列
IMAGE_SAVE_PATH = r'E:\000photo\漫画柜\final.jpg' # 图片转换后的地址# 获取图片集地址下的所有图片名称
image_names = [name for name in os.listdir(IMAGES_PATH) for item in IMAGES_FORMAT ifos.path.splitext(name)[1] == item]print("image_names", image_names)
# 简单的对于参数的设定和实际图片集的大小进行数量判断
if len(image_names) != IMAGE_ROW * IMAGE_COLUMN:raise ValueError("合成图片的参数和要求的数量不能匹配!")# 定义图像拼接函数
def image_compose():to_image = Image.new('RGB', (IMAGE_COLUMN * IMAGE_SIZE, IMAGE_ROW * IMAGE_SIZE)) # 创建一个新图# 循环遍历,把每张图片按顺序粘贴到对应位置上for y in range(1, IMAGE_ROW + 1):for x in range(1, IMAGE_COLUMN + 1):from_image = Image.open(IMAGES_PATH + image_names[IMAGE_COLUMN * (y - 1) + x - 1]).resize((IMAGE_SIZE, IMAGE_SIZE), Image.ANTIALIAS)to_image.paste(from_image, ((x - 1) * IMAGE_SIZE, (y - 1) * IMAGE_SIZE))return to_image.save(IMAGE_SAVE_PATH) # 保存新图image_compose() # 调用函数
我的原图片:


其实这个代码有俩个我觉得要优化的地方:
第一个就是:要求的图片的数量,我想改成合并的图片的列自己定义,行随着数量的增加自动往下增加。
第二个就是:我想把原图片的形状保持不变。
2、优化第一个数量问题:
这个代码改动较少,不过已经达到了数量问题。
import osimport PIL.Image as ImageIMAGES_PATH = r'E:\000photo\漫画柜\\' # 图片集地址
IMAGES_FORMAT = ['.jpg', '.JPG'] # 图片格式
IMAGE_SIZE = 256 # 每张小图片的大小IMAGE_COLUMN = 5 # 图片间隔,也就是合并成一张图后,一共有几列
IMAGE_SAVE_PATH = r'E:\000photo\漫画柜final.jpg' # 图片转换后的地址
# 获取图片集地址下的所有图片名称
image_names = [name for name in os.listdir(IMAGES_PATH) for item in IMAGES_FORMAT ifos.path.splitext(name)[1] == item]
# IMAGE_ROW = 4 # 图片间隔,也就是合并成一张图后,一共有几行
IMAGE_ROW_yu = len(image_names) % IMAGE_COLUMN
if IMAGE_ROW_yu == 0:IMAGE_ROW = len(image_names) // IMAGE_COLUMN
else:IMAGE_ROW = len(image_names) // IMAGE_COLUMN + 1print("image_names", image_names)# 定义图像拼接函数
def image_compose():to_image = Image.new('RGB', (IMAGE_COLUMN * IMAGE_SIZE, IMAGE_ROW * IMAGE_SIZE)) # 创建一个新图# 循环遍历,把每张图片按顺序粘贴到对应位置上total_num = 0for y in range(1, IMAGE_ROW + 1):for x in range(1, IMAGE_COLUMN + 1):from_image = Image.open(IMAGES_PATH + image_names[IMAGE_COLUMN * (y - 1) + x - 1]).resize((IMAGE_SIZE, IMAGE_SIZE), Image.ANTIALIAS)to_image.paste(from_image, ((x - 1) * IMAGE_SIZE, (y - 1) * IMAGE_SIZE))total_num += 1if total_num == len(image_names):breakreturn to_image.save(IMAGE_SAVE_PATH) # 保存新图image_compose() # 调用函数

可以看到,当我图片不是正好是行列的倍数时,不影响图片的拼接合并。
3、优化俩个问题(数量不限+性状按比例变小)
这个代码几乎全部改了,我重新按自己想要的效果逻辑改动的,最后合并的像素宽和高是从图片列表中去80%的位置图片的宽和高(排序之后),这样可以百分之80的图片是完全显示的,可能其他的不是全部显示,但是原图的形状是没有变化。
import osimport PIL.Image as Imagedef resize_by_width(infile, image_size):"""按照宽度进行所需比例缩放"""im = Image.open(infile)(x, y) = im.sizelv = round(x / image_size, 2) + 0.01x_s = int(x // lv)y_s = int(y // lv)print("x_s", x_s, y_s)out = im.resize((x_s, y_s), Image.ANTIALIAS)return outdef get_new_img_xy(infile, image_size):"""返回一个图片的宽、高像素"""im = Image.open(infile)(x, y) = im.sizelv = round(x / image_size, 2) + 0.01x_s = x // lvy_s = y // lv# print("x_s", x_s, y_s)# out = im.resize((x_s, y_s), Image.ANTIALIAS)return x_s, y_s# 定义图像拼接函数
def image_compose(image_colnum, image_size, image_rownum, image_names, image_save_path, x_new, y_new):to_image = Image.new('RGB', (image_colnum * x_new, image_rownum * y_new)) # 创建一个新图# 循环遍历,把每张图片按顺序粘贴到对应位置上total_num = 0for y in range(1, image_rownum + 1):for x in range(1, image_colnum + 1):from_image = resize_by_width(image_names[image_colnum * (y - 1) + x - 1], image_size)# from_image = Image.open(image_names[image_colnum * (y - 1) + x - 1]).resize((image_size,image_size ), Image.ANTIALIAS)to_image.paste(from_image, ((x - 1) * x_new, (y - 1) * y_new))total_num += 1if total_num == len(image_names):breakreturn to_image.save(image_save_path) # 保存新图def get_image_list_fullpath(dir_path):file_name_list = os.listdir(dir_path)image_fullpath_list = []for file_name_one in file_name_list:file_one_path = os.path.join(dir_path, file_name_one)if os.path.isfile(file_one_path):image_fullpath_list.append(file_one_path)else:img_path_list = get_image_list_fullpath(file_one_path)image_fullpath_list.extend(img_path_list)return image_fullpath_listdef merge_images(image_dir_path,image_size,image_colnum):# 获取图片集地址下的所有图片名称image_fullpath_list = get_image_list_fullpath(image_dir_path)print("image_fullpath_list", len(image_fullpath_list), image_fullpath_list)image_save_path = r'{}.jpg'.format(image_dir_path) # 图片转换后的地址# image_rownum = 4 # 图片间隔,也就是合并成一张图后,一共有几行image_rownum_yu = len(image_fullpath_list) % image_colnumif image_rownum_yu == 0:image_rownum = len(image_fullpath_list) // image_colnumelse:image_rownum = len(image_fullpath_list) // image_colnum + 1x_list = []y_list = []for img_file in image_fullpath_list:img_x, img_y = get_new_img_xy(img_file, image_size)x_list.append(img_x)y_list.append(img_y)print("x_list", sorted(x_list))print("y_list", sorted(y_list))x_new = int(x_list[len(x_list) // 5 * 4])y_new = int(x_list[len(y_list) // 5 * 4])image_compose(image_colnum, image_size, image_rownum, image_fullpath_list, image_save_path, x_new, y_new) # 调用函数# for img_file in image_fullpath_list:# resize_by_width(img_file,image_size)if __name__ == '__main__':image_dir_path = r'E:\000photo\美女' # 图片集地址image_size = 128 # 每张小图片的大小image_colnum = 10 # 合并成一张图后,一行有几个小图merge_images(image_dir_path, image_size, image_colnum)
因为图片整的比较多。

截图小部分:

最后可以看出,原图片的形状没有变化,至此,弄了俩个小时,总算弄成我想要的效果了。
如果觉得不错,欢迎点赞+关注
4、优化黑行高度问题
最近有三个小伙伴私信我,说黑白行问题,今天决定再撸下一年多前的代码。
然后开始过一遍之前的代码,发现之前有个地方写错了,我当时也没有发现,竟然这么多人看我代码了,也没有懂Python的小伙伴给我提醒下么???
主要就是之前的:
y_new = int(x_list[len(y_list) // 5 * 4])
这个地方x_list应该是y_list,改下就可以了。
y_new = int(y_list[len(y_list) // 5 * 4])
感觉小伙伴们也不咋动手,我还是吧完整的粘贴出来吧。
import osimport PIL.Image as Imagedef resize_by_width(infile, image_size):"""按照宽度进行所需比例缩放"""im = Image.open(infile)(x, y) = im.sizelv = round(x / image_size, 2) + 0.01x_s = int(x // lv)y_s = int(y // lv)print("x_s", x_s, y_s)out = im.resize((x_s, y_s), Image.ANTIALIAS)return outdef get_new_img_xy(infile, image_size):"""返回一个图片的宽、高像素"""im = Image.open(infile)(x, y) = im.sizelv = round(x / image_size, 2) + 0.01x_s = x // lvy_s = y // lv# print("x_s", x_s, y_s)# out = im.resize((x_s, y_s), Image.ANTIALIAS)return x_s, y_s# 定义图像拼接函数
def image_compose(image_colnum, image_size, image_rownum, image_names, image_save_path, x_new, y_new):to_image = Image.new('RGB', (image_colnum * x_new, image_rownum * y_new)) # 创建一个新图# 循环遍历,把每张图片按顺序粘贴到对应位置上total_num = 0for y in range(1, image_rownum + 1):for x in range(1, image_colnum + 1):from_image = resize_by_width(image_names[image_colnum * (y - 1) + x - 1], image_size)# from_image = Image.open(image_names[image_colnum * (y - 1) + x - 1]).resize((image_size,image_size ), Image.ANTIALIAS)to_image.paste(from_image, ((x - 1) * x_new, (y - 1) * y_new))total_num += 1if total_num == len(image_names):breakreturn to_image.save(image_save_path) # 保存新图def get_image_list_fullpath(dir_path):file_name_list = os.listdir(dir_path)image_fullpath_list = []for file_name_one in file_name_list:file_one_path = os.path.join(dir_path, file_name_one)if os.path.isfile(file_one_path):image_fullpath_list.append(file_one_path)else:img_path_list = get_image_list_fullpath(file_one_path)image_fullpath_list.extend(img_path_list)return image_fullpath_listdef merge_images(image_dir_path,image_size,image_colnum):# 获取图片集地址下的所有图片名称image_fullpath_list = get_image_list_fullpath(image_dir_path)print("image_fullpath_list", len(image_fullpath_list), image_fullpath_list)image_save_path = r'{}.jpg'.format(image_dir_path) # 图片转换后的地址# image_rownum = 4 # 图片间隔,也就是合并成一张图后,一共有几行image_rownum_yu = len(image_fullpath_list) % image_colnumif image_rownum_yu == 0:image_rownum = len(image_fullpath_list) // image_colnumelse:image_rownum = len(image_fullpath_list) // image_colnum + 1x_list = []y_list = []for img_file in image_fullpath_list:img_x, img_y = get_new_img_xy(img_file, image_size)x_list.append(img_x)y_list.append(img_y)print("x_list", sorted(x_list))print("y_list", sorted(y_list))x_new = int(x_list[len(x_list) // 5 * 4])y_new = int(y_list[len(y_list) // 5 * 4])print(" x_new, y_new", x_new, y_new)image_compose(image_colnum, image_size, image_rownum, image_fullpath_list, image_save_path, x_new, y_new) # 调用函数# for img_file in image_fullpath_list:# resize_by_width(img_file,image_size)if __name__ == '__main__':image_dir_path = r'C:\Users\user\Downloads\archives\赵丽颖壁纸_-_国内版_Bing_images' # 图片集地址image_size = 128 # 每张小图片的大小image_colnum = 10 # 合并成一张图后,一行有几个小图merge_images(image_dir_path, image_size, image_colnum)
给大家上个效果图:

5、合成图片不清晰问题:
这个主要是像素同比例缩小导致的,我这里image_size = 128 ,该我720,就特别清晰了。

总结下:
给学习编程的小伙伴一个建议:学习人家代码时候,大家可以先读懂人家的代码,自己尝试修改,看效果。
最后可以看出,原图片的形状没有变化,至此,黑白问题已经修改。
如果觉得不错,欢迎点赞+关注哈



















