这是我去年选修python程序设计时候的作业四,当时是皇甫伟老师教的然后范茜莹姐姐当的助教还代了两节课(虽然我作为颜狗沉迷颜值没好好听就是了),但是,python程序设计还是值得我来安利的,大二计通贝壳er都去选!!!
前文链接:
- python程序设计之turtle绘图
- Python程序设计之词频统计
- Python程序设计之数字华容道
目录
作业要求
设计思路
运行结果
心得体会
源代码附上
作业要求
你打算用照片做一个照片墙,也就是在一张图片(背景墙)上的不同位置放了很多小图片。于是你收集了一些图片(如风景照等),你要做的工作包括下面的任务:
(1)将所收集的图片进行切分,切成一个个小单元,准备嵌入在照片墙。
(2)用上述单元在在照片墙上拼出数字图案,该数字是你的学号。
设计思路(1)使用Pillow分别构建同样大小的图片text.jpg、wall.jpg,再根据两张图片的相同位置的像素情况构建final.jpg
(2)首先将图片统一重命名待用。然后创建text.jpg来存放照片墙的文字图层:
text = "41921012" # 设置文字图层内容
font = ImageFont.truetype("arial.ttf", int(MAX_HEIGHT*1)) # 选择字体和字体大小
text_image = Image.new("RGB", (MAX_WIDTH,MAX_HEIGHT)) # 新建一张空图
draw = ImageDraw.Draw(text_image)
draw.text((0,0), text,font = font,fill = "red") # 写入字
text_image.save("text.jpg")
之后随机选择照片,调整其大小,按顺序粘贴组成一张大的图片wall.jpg来存放照片墙的背景图层:
wall_image = Image.new("RGB", (MAX_WIDTH,MAX_HEIGHT)) # 新建空图
# 通过循环粘贴小图片成大图片
for x in range(MAX_WIDTH//MIN_WIDTH):
for y in range(MAX_HEIGHT//MIN_HEIGHT):
num = random.randint(1,5) # 随机选图
tmp = Image.open("photo/"+str(num)+".jpg")
tmp = tmp.resize((MIN_WIDTH,MIN_HEIGHT),Image.NEAREST) # 调整大小
wall_image.paste(tmp,(x*MIN_WIDTH,y*MIN_HEIGHT)) #粘贴图片
wall_image.save("wall.jpg")
最后新建一张大小一样的图片final.jpg,通过Pillow.getpixel()获取两张图的像素信息,逐个像素进行比较,若text.jpg中的一点像素为红色,则对final.jpg的同一点使用Pillow.putpixel()赋同一点处wall.jpg的像素信息:
final_image = Image.new("RGB", (MAX_WIDTH,MAX_HEIGHT)) # 新建空图
# 循环比较各个位置像素点
for l in range(MAX_WIDTH):
for h in range(MAX_HEIGHT):
dot = (l,h)
color_1 = text_image.getpixel(dot)
color_2 = wall_image.getpixel(dot)
if color_1 == (255,0,0): # 如果该点处text.jpg为大红色
final_image.putpixel(dot,color_2) # 将该图的像素点赋值为wall.jpg同样位置像素点的值
final_image.save("final.jpg")
运行结果
(1)text:
(2)wall:
(3)final:
心得体会
在调试过程中,整体上比较顺利,中间遇到了几个问题简单总结以下:
- 一开始比较无从下手,在请教了同学之后才有了思路,实际实现类似于PS的蒙版 *** 作;
- 选择的图片格式有要求,我一开始选用的是.tif格式的照片,但实际运行的时候发现图片过大超出PIL库能运行的最大像素值,相同的图片格式改为jpg,jpeg等等都可以极大的加快程序运行速度。
import os
from PIL import Image,ImageFont,ImageDraw
import random
MIN_WIDTH = 100
MIN_HEIGHT = 100
MAX_HEIGHT = 1000
MAX_WIDTH = 4500
path = 'photo'
num = 1
for file in os.listdir(path):
os.rename(os.path.join(path,file),os.path.join(path,str(num)+".jpg"))
num+=1
text = "41921012" # 设置文字图层内容
font = ImageFont.truetype("arial.ttf", int(MAX_HEIGHT*1)) # 选择字体和字体大小
text_image = Image.new("RGB", (MAX_WIDTH,MAX_HEIGHT)) # 新建一张空图
draw = ImageDraw.Draw(text_image)
draw.text((0,0), text,font = font,fill = "red") # 写入字
text_image.save("text.jpg")
wall_image = Image.new("RGB", (MAX_WIDTH,MAX_HEIGHT)) # 新建空图
# 通过循环粘贴小图片成大图片
for x in range(MAX_WIDTH//MIN_WIDTH):
for y in range(MAX_HEIGHT//MIN_HEIGHT):
num = random.randint(1,5) # 随机选图
tmp = Image.open("photo/"+str(num)+".jpg")
tmp = tmp.resize((MIN_WIDTH,MIN_HEIGHT),Image.NEAREST) # 调整大小
wall_image.paste(tmp,(x*MIN_WIDTH,y*MIN_HEIGHT)) #粘贴图片
wall_image.save("wall.jpg")
final_image = Image.new("RGB", (MAX_WIDTH,MAX_HEIGHT)) # 新建空图
# 循环比较各个位置像素点
for l in range(MAX_WIDTH):
for h in range(MAX_HEIGHT):
dot = (l,h)
color_1 = text_image.getpixel(dot)
color_2 = wall_image.getpixel(dot)
if color_1 == (255,0,0): # 如果该点处text.jpg为大红色
final_image.putpixel(dot,color_2) # 将该图的像素点赋值为wall.jpg同样位置像素点的值
final_image.save("final.jpg")
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)