【Python学习】趣味工具-一键制作照片墙

一、实现目标

        制作一个照片墙生成器,可以实现照片墙一键生成和定制图案的功能。例如下图:

二、实现步骤

        如果要在家中做一面这样的照片墙需要怎么做呢?先找一个大背景,比如白色的墙壁。然后设计一个图形,比如心形。最后把选好的照片粘贴到设计好的图形中,就OK了。

        使用python来实现这一切,过程也是类似的,接下来我们就来实现这个过程吧。

2.1 设计图形

        画图,太简单了,用ppt就能轻松搞定心的图案,就像这样!

2.2 图形编码

        接下来需要对图形进行编码,编码的目的是标示,那块需要粘贴照片,那块需要留白;需要用到一个第三方视觉处理模块pillow,具体的步骤如下:

1、安装pillow

pip3 install pillow

3、导入pillow

        安装好pillow之后,导入pillow模块,因为本项目只需要使用到PIL模块中的Image类。所以我们使用from PIL import Image语句导入Image类。

# 导入PIL模块
import PIL
# 从PIL库中导入Image类
from PIL import Image

4、打开图片

        使用Image类的open()方法可以打开图片

# 使用open()方法打开路径"D:/学习资料/Python/stest/xinxing.png"中的图片
# 赋值给变量img
img = Image.open("D:/学习资料/Python/stest/xinxing.png")

5、图片转换

        用Image.open()打开图片时,返回的对象模式都是"RGB"。由于RGB模式的图片实际上是由三个通道编码构成,而我们需要单通道的编码格式。所以需要使用convert()函数将RGB图片转化单通道的二值图像。

# 使用convert()函数将图片转化为二值图片
# 赋值给变量img_1
img_1=img.convert("1")

        convert()函数,作用是将RGB模式的图像转化为其他模式的图像。共九种不同模式如下:1,L,P,RGB,RGBA,CMYK,YCbCr,I,F。有兴趣的同学了可了解一下。“1”表示将图片转化为二值图片。

        二值图像:由于计算机采用二进制编码,bit是二进制编码中表示信息的最小单位,每个bit只有"0"和"1"两个取值,因而n个bit的信息量可以表现出2的n次方种选择。二值图像的每个像素用8个bit表示,所以8个bit构成的像素取值范围为0~255。又因为二值图片只有黑、白两种颜色,所以每个像素值为0时表示该像素点为黑色,255表示该像素点为白色。

6、调整大小

        在进行编码前,我们还需要调整图片大小。因为图片越大,像素点越密,生成图片的密度也就更大。为了防止图片过于密集,我们可以使用 resize() 方法重新设置图片的像素宽度为20px,长度为20px。

# 把图像的size重新设定为(10,10),也就是宽20像素,长20像素
# 赋值给变量new_img
new_img = img_1.resize((20,20))

7、生成嵌套列表

        接下来就可以编码了,现在图片宽20像素,长20像素,每个像素值都是0或者255,其中0代表黑色,255代表白色。我们可以依次读取每一个点的像素值,并将一行的数值都存储到一个列表中。这样依次读取,直到读完全部20行,20列并将所有数值都存储到新列表中,就生成了嵌套列表。读取像素值可以使用 getpixel() 方法,参数是一个坐标点,形式是元组。

# 定义一个空列表list
list = []
# 使用for循环遍历0到19
for i in range(20):
    # 定义一个空列表row存储一行中每个点的值
    row = []
    # 使用for循环遍历0到19
    for j in range(20):
        # 使用getpixel方法获取图像中某一点像素的RGB颜色值
        pix = new_img.getpixel((j,i))
        # 将颜色值中的255转化为1
        new_pix = pix % 254
        # 将像素值依次存储到列表row中
        row.append(new_pix)
    # 依次打印像素坐标
    print(row)
    # 将每一行值存储在列表figure中      
    list.append(row)

        之后我们就得到一个嵌套列表

2.3 制作照片墙

        最终我们是将图片粘贴在一个背景墙上,所以需要准备一个纯色背景图片,然后从文件夹中获取想要粘贴的照片,将它贴在爱心的对应位置即可。

1、设置纯色背景

        读取一张纯色的背景图片,并设置图片大小。我们将每张图片的大小设置为长100,宽100。整个照片墙一共有20行20列,那么照片墙的背景图片大小为长2000,宽2000。

# 设置单张图片的像素,图片宽度pic_width为100像素,长度pic_height为100像素
pic_width = 100
pic_height = 100

# 读取路径为"D:/学习资料/Python/stest/gray.png"的背景图片
# 将背景图片的尺寸设置为(2000,2000)
img_back = Image.open("D:/学习资料/Python/stest/gray.png").resize((2000,2000))

2、获取照片

        使用os模块的listdir()方法获取照片名称列表。

# 导入os模块
import os
# 获取文件夹"D:/学习资料/Python/stest/maomi"内文件名称所组成的列表
image_names = os.listdir("D:/学习资料/Python/stest/maomi")

3、粘贴照片

        接下来我们遍历列表的每一行每一列,在数值为0的坐标位置随机粘贴一张文件夹中的照片就行啦。PIL中的paste()函数的作用为将一张图片覆盖到另一张图片的指定位置去。例如:img_back.paste(pic,(400,500))表示将图片pic粘贴到img_back的(400,500)的位置上去。

        例如:第一个粘贴的位置是第6列第5行,图片宽度为100,高度为100。那么坐标值为(500,400)。(注:坐标值为左上角的坐标)

        最后使用Iamge类的save()方法将图片保存到指定位置即可。

# 导入random库
import random
# 遍历行和列,判断当数值为0时
for row in range(20):
    for column in range(20):
        if list[row][column] == 0:
            # 随机选取文件夹kitten中的一张照片,把图片路径赋值给变量ran_photo
            ran_photo = "D:/学习资料/Python/stest/maomi/" + random.choice(image_names)
            # 打开随机选中的照片,并且将照片的尺寸设置宽度为pic_width,高度为pic_height
            pic = Image.open(ran_photo).resize((pic_width,pic_height))
            # 使用paste()函数将选中的照片依次粘贴到照片背景img_back中
            # 参数设置为需要粘贴的图片pic,粘贴的位置图片宽度*列,图片高度*行
            img_back.paste(pic,(pic_width * column, pic_height * row))
# 将图片保存到路径:"D:/学习资料/Python/stest/result.png"中            
img_back.save("D:/学习资料/Python/stest/result.png")

三、总结

        完整代码如下:

# 导入PIL模块
import PIL
# 从PIL库中导入Image类
from PIL import Image

# 使用open()方法打开路径"D:/学习资料/Python/stest/xinxing.png"中的图片
# 赋值给变量img
img = Image.open("D:/学习资料/Python/stest/xinxing.png")

# 使用convert()函数将图片转化为二值图片
# 赋值给变量img_1
img_1=img.convert("1")

# 把图像的size重新设定为(10,10),也就是宽20像素,长20像素
# 赋值给变量new_img
new_img = img_1.resize((20,20))

# 定义一个空列表list
list = []
# 使用for循环遍历0到19
for i in range(20):
    # 定义一个空列表row存储一行中每个点的值
    row = []
    # 使用for循环遍历0到19
    for j in range(20):
        # 使用getpixel方法获取图像中某一点像素的RGB颜色值
        pix = new_img.getpixel((j,i))
        # 将颜色值中的255转化为1
        new_pix = pix % 254
        # 将像素值依次存储到列表row中
        row.append(new_pix)
    # 依次打印像素坐标
    print(row)
    # 将每一行值存储在列表figure中      
    list.append(row)

# 设置单张图片的像素,图片宽度pic_width为100像素,长度pic_height为100像素
pic_width = 100
pic_height = 100

# 读取路径为"D:/学习资料/Python/stest/blue.png"的背景图片
# 将背景图片的尺寸设置为(2000,2000)
img_back = Image.open("D:/学习资料/Python/stest/gray.png").resize((2000,2000))

# 导入os模块
import os
# 获取文件夹"D:/学习资料/Python/stest/maomi"内文件名称所组成的列表
image_names = os.listdir("D:/学习资料/Python/stest/maomi")

# 导入random库
import random
# 遍历行和列,判断当数值为0时
for row in range(20):
    for column in range(20):
        if list[row][column] == 0:
            # 随机选取文件夹kitten中的一张照片,把图片路径赋值给变量ran_photo
            ran_photo = "D:/学习资料/Python/stest/maomi/" + random.choice(image_names)
            # 打开随机选中的照片,并且将照片的尺寸设置宽度为pic_width,高度为pic_height
            pic = Image.open(ran_photo).resize((pic_width,pic_height))
            # 使用paste()函数将选中的照片依次粘贴到照片背景img_back中
            # 参数设置为需要粘贴的图片pic,粘贴的位置图片宽度*列,图片高度*行
            img_back.paste(pic,(pic_width * column, pic_height * row))
# 将图片保存到路径:"D:/学习资料/Python/stest/result.png"中            
img_back.save("D:/学习资料/Python/stest/result.png")

        执行结果如下: 

        本实例使用 pillow、os、random 模块制作一个照片墙生成器,可以实现照片墙一键生成和定制图案的功能。

        pillow 模块是一个开源的图像处理模块。它的原生是PIL(Python Imaging Library)pillow 可以完成很多图片处理功能,比如图像滤镜,裁切,模糊等等。pillow在图片处理的功能比较丰富,在人工智能应用场景中进行图像识别也会使用pillow进行图像分割,关键特征提取等等功能。 

        os 模块是Python的标准库模块,用于与操作系统进行交互的模块,它提供了许多函数和方法来执行文件和目录操作、进程管理、环境变量访问等。

  random模块是Python的标准库模块,其提供了一个伪随机数生成器的工具包,它可以生成随机数,进行随机序列操作,以及模拟随机性事件。虽然生成的数字实际上是伪随机的,但它们在大多数应用中足够随机。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

西攻城狮北

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值