之前分享过 python 文件代码转图片(2)内容,改了一下,可以生成卡片似的图片,主要模拟微信读书笔记。
提供文字内容即可, 颜色,背景图片,什么都可以配置,修改配置文件内容即可。
改改代码,也可以做个日历,单词卡片或者爬取网页内容直接生成图片等。
源代码:
config.py
# 背景图片
BG_WIDTH = 400
BG_MARGIN = 20 #边距
BG_COLOR = 'lightskyblue'
# 字体文字
FONT_PATH = "resource/logo体.otf"
FONT_SIZE = 20
TEXT_COLOR = 'white'
# 二维码
QR_IMAGE_PATH = 'resource/code.jpg'
QR_WIDTH = 80
QR_HEIGHT = 80
# 头像
LOGO_PATH = 'resource/yezi.jpg'
LOGO_WIDTH = 40
LOGO_HEIGHT = 40
# 文字信息
TITLE = '算法练习题'
TIP = '更多内容 请关注叶子陪你玩'
TEXT = """问题描述:
有n个人围成一圈,从1开始按顺序编号,从第一个人开始从1到k(假设k=3)报数,报到k的人退出圈子,然后圈子缩小,从下一个人继续游戏,问最后留下的是原来的第几号。"""
# 输出图片名称
OUTPUT_IMAGE = '卡片.jpg'
main.py
from PIL import Image,ImageDraw,ImageFont
import matplotlib.pyplot as plt
import config
'''将文本按照字体大小,图片大小进行换行处理'''
def process_text(text,bg_width,bg_margin,font_size):
''''''
# 每行文字个数
line_words = int((bg_width - bg_margin * 4) // font_size)
new_text = ""
count = 0
for word in text:
count += 1
if word != '\n':
if count <= line_words and ord(word) >= 255:
new_text += word
elif count <= line_words and ord(word) < 255:
new_text = new_text + " " + word + " "
else:
new_text += '\n'
count = 0
else:
count = 0
new_text += "\n"
return new_text
'''计算文本对象的宽度和高度'''
def cal_textobj_w_h(new_text,font_path,font_size):
font = ImageFont.truetype(font_path, font_size)
img = Image.new("RGB", (100, 100), 'white')
# 将图片转换成绘图模式
draw = ImageDraw.Draw(img)
w, h = draw.textsize(new_text, font=font)
return w,h
'''粘贴图片'''
def paste_image(imgobj1, imgobj2, x,y,alpha = False):
if not alpha:
imgobj1.paste(imgobj2,(x,y))
else:
imgobj1.paste(imgobj2, (x, y),imgobj2)
return imgobj1
'''写入文字'''
def write_text(imgobj,x,y,text,text_color,font_path,font_size):
font = ImageFont.truetype(font_path, font_size)
# 将图片转换成绘图可编辑模式
draw = ImageDraw.Draw(imgobj)
# 在 图片中间 位置 写入内容:hello world 文字颜色:黑色
draw.text((x,y), text, fill=text_color, font=font)
return imgobj
'''划线'''
def draw_line(imgobj,x1,y1,x2,y2,line_color,line_width):
# 将图片转换成绘图可编辑模式
draw = ImageDraw.Draw(imgobj)
# 在 图片中间 位置 写入内容:hello world 文字颜色:黑色
draw.line((x1,y1,x2,y2),line_color,line_width)
return imgobj
'''生成卡片'''
def generate_card(text):
# 文本处理
new_text = process_text(text,config.BG_WIDTH,config.BG_MARGIN,config.FONT_SIZE)
# 计算标题文本对象宽度和高度
title_w,title_h = cal_textobj_w_h(config.TITLE,config.FONT_PATH,config.FONT_SIZE)
# 计算文本对象的宽度和高度
text_w,text_h = cal_textobj_w_h(new_text,config.FONT_PATH,config.FONT_SIZE)
# 打开二维码图片
qr_image = Image.open(config.QR_IMAGE_PATH).resize((config.QR_WIDTH,config.QR_HEIGHT))
# 题卡
card_w = config.BG_WIDTH
card_h = title_h + text_h + config.QR_HEIGHT + 6*config.BG_MARGIN
card = Image.new('RGB',(card_w,card_h),config.BG_COLOR)
# 粘贴logo头像
logo = Image.open(config.LOGO_PATH).convert("RGBA")
# 新建一张黑色图片,并转换成 L灰度图 同时要和 img大小一样
mask = Image.new('L', (logo.size[0], logo.size[1]), 0)
draw = ImageDraw.Draw(mask)
# 绘制一个白色圆形
draw.ellipse((0, 0, mask.size[0], mask.size[1]), fill=255)
logo.putalpha(mask)
card = paste_image(card,logo.resize((config.LOGO_WIDTH,config.LOGO_HEIGHT)),20,10,alpha = True)
# 写入标题
title_x,title_y = (card_w-title_w)//2,config.BG_MARGIN
card = write_text(card,title_x,title_y,config.TITLE,config.TEXT_COLOR,config.FONT_PATH,config.FONT_SIZE)
# 划线
card = draw_line(card,config.BG_MARGIN,title_h+2*config.BG_MARGIN,card_w-config.BG_MARGIN,title_h+2*config.BG_MARGIN,'white',2)
# 写入题目
text_x, text_y = (card_w-text_w)//2, title_h + 3*config.BG_MARGIN
card = write_text(card, text_x, text_y, new_text, config.TEXT_COLOR, config.FONT_PATH, config.FONT_SIZE)
# 划线
card = draw_line(card,config.BG_MARGIN,text_y + text_h + config.BG_MARGIN,card_w-config.BG_MARGIN,text_y + text_h + config.BG_MARGIN,'white',2)
# 提示信息
card = write_text(card, text_x, text_y + text_h + 3.5*config.BG_MARGIN, config.TIP, config.TEXT_COLOR, config.FONT_PATH, config.FONT_SIZE)
# 粘贴二维码
qr_x,qr_y = card_w - config.BG_MARGIN - config.QR_WIDTH,card_h - config.BG_MARGIN - config.QR_HEIGHT
card = paste_image(card,qr_image,qr_x,qr_y)
# 显示预览
plt.imshow(card)
plt.show()
return card
if __name__ == '__main__':
text = config.TEXT
card = generate_card(text)
card.save(config.OUTPUT_IMAGE)