• 售前

  • 售后

热门帖子
入门百科

Python生成截图选餐GIF动画

[复制链接]
无人岛屿颈 显示全部楼层 发表于 2021-8-14 13:19:51 |阅读模式 打印 上一主题 下一主题
目次


  • python生成笔墨动图

    • 下载心情图片到本地
    • 分析动图
    • 生成单张图片
    • 爬取菜品数据
    • 生成菜名动图

  • PIL操纵gif的其他操纵

    • Gif拆分
    • GIF倒放

之前群里有小同伴问本日中午该吃什么,然后另一位小同伴发了一张下面的动图:

我个人以为还挺有意思的,截图还真像抽奖一样随机选一个菜名。考虑到这张动图中的菜名候选并不见得都是我们可以或许吃的菜。我们可以用python根据菜名列表生成如许的动图玩玩。
之前还看到什么截图选头像之类的动图,那类通过图片生成的动图都比较简单,通过文中提到的Imagine的动画作坊工具就可以做。所以本文只演示怎样生成笔墨动图。

python生成笔墨动图

下面我们一步步来完成这个操纵:

下载心情图片到本地

为了分析这种心情图片,第一步需要先下载下来,但是对于微信的心情动图,颠末测试还真没法直接下载下来。
虽然通过文件监控工具分析出,gif心情动图存储位置在
  1. C:\Users\ASUS\Documents\WeChat Files\你的微信ID\FileStorage\CustomEmotion\xx\xxxx
复制代码
位置,但是却无法用图片工具检察。用winhex分析二进制得到了
  1. V1MMWX
复制代码
如许的文件头,说明微信对心情都举行了一定程度的加密。虽然可以解密,但如许大动干戈未免过于麻烦。
后面终于想到了一个简单的方案,那就是把向你有权限登录背景的公众号发送这个心情,再去公众号背景下载:

微信发送的动图都是存储为自己特有
  1. V1MMWX
复制代码
加密格式,大概是为了使用自己独创的压缩算法有更大的压缩比吧。那说明我们想直接看本地微信存储的gif动图,只能自行开发专门针对这种微信格式的解码器了。

分析动图

下面我使用小工具Imagine,并使用动画作坊打开:

可以看到这张动图由22张笔墨图片构成,帧切换时间为20毫秒。

生成单张图片

分析完成我们考虑用PIL库来生成单张图片,如果还没有安装该库的童鞋,使用以下命令安装该库:
  1. pip install pillow
复制代码
下面选择了用蓝底做背景。我们先来绘制中央的菜名笔墨:
  1. from PIL import Image, ImageFont, ImageDraw
  2. text = "珍珠土豆焖牛腩"
  3. size = 320
  4. fontsize = (size-20)//len(text)
  5. im = Image.new(mode='RGB', size=(size, size), color="lightblue")
  6. draw = ImageDraw.Draw(im=im)
  7. draw.text(xy=(10, (size-fontsize*1.5)/2),
  8.           text=text, fill=0,
  9.           font=ImageFont.truetype('msyh.ttc', size=fontsize))
  10. im
复制代码

由于菜品的名字笔墨个数差异等,为了都能填满整图,作了主动笔墨巨细调解处置处罚。
字体我选择了微软雅黑,当然微软雅黑也有三种子字体,可以通过系统字体安装目次检察字体文件的属性从而知道字体对应的文件名:

下方带阴影的的笔墨生成起来会麻烦一些,我的思绪是先绘制纯黑的笔墨,在绘制带黑色边缘白色添补的笔墨向上偏移几个单元:
  1. def text_border(text, x, y, font, shadowcolor, fillcolor):
  2.     draw.text((x - 1, y), text, font=font, fill=shadowcolor)
  3.     draw.text((x + 1, y), text, font=font, fill=shadowcolor)
  4.     draw.text((x, y - 1), text, font=font, fill=shadowcolor)
  5.     draw.text((x, y + 1), text, font=font, fill=shadowcolor)
  6.     draw.text((x - 1, y - 1), text, font=font, fill=shadowcolor)
  7.     draw.text((x + 1, y - 1), text, font=font, fill=shadowcolor)
  8.     draw.text((x - 1, y + 1), text, font=font, fill=shadowcolor)
  9.     draw.text((x + 1, y + 1), text, font=font, fill=shadowcolor)
  10.     draw.text((x, y), text, font=font, fill=fillcolor)
  11. bottomtext = "不知道吃什么?截图吃饭"
  12. bottom_fontsize = 27
  13. bottom_font = ImageFont.truetype('STHUPO.TTF', size=bottom_fontsize)
  14. x, y = (size-bottom_fontsize*len(bottomtext))/2, size-bottom_fontsize*1.2
  15. draw.text(xy=(x, y), text=bottomtext,
  16.           fill=0, font=bottom_font)
  17. text_border(bottomtext, x, y-4,
  18.             bottom_font, 0, (255, 255, 255))
  19. im
复制代码
  1. 上述代码选择了华文琥珀作为字体,个人用来绘制文字边框的方法比较简单粗暴,如果有更好的办法,欢迎留言交流。
复制代码
考虑到后续图片发送到微信上显示都很小,干脆现在就压缩一下像素巨细:
  1. im.thumbnail((128, 128))
  2. im
复制代码

下面我们封装一下生成代码,方便后续调用:
  1. from PIL import Image, ImageFont, ImageDraw
  2. def text_img(text, bgcolor="lightblue", bottomtext="不知道吃什么?截图吃饭", size=360, result_size=(128, 128)):
  3.     def text_border(text, x, y, font, shadowcolor, fillcolor):
  4.         draw.text((x - 1, y), text, font=font, fill=shadowcolor)
  5.         draw.text((x + 1, y), text, font=font, fill=shadowcolor)
  6.         draw.text((x, y - 1), text, font=font, fill=shadowcolor)
  7.         draw.text((x, y + 1), text, font=font, fill=shadowcolor)
  8.         draw.text((x - 1, y - 1), text, font=font, fill=shadowcolor)
  9.         draw.text((x + 1, y - 1), text, font=font, fill=shadowcolor)
  10.         draw.text((x - 1, y + 1), text, font=font, fill=shadowcolor)
  11.         draw.text((x + 1, y + 1), text, font=font, fill=shadowcolor)
  12.         draw.text((x, y), text, font=font, fill=fillcolor)
  13.     im = Image.new(mode='RGB', size=(size, size), color=bgcolor)
  14.     draw = ImageDraw.Draw(im=im)
  15.     fontsize = (size-20)//len(text)
  16.     draw.text(xy=(10, (size-fontsize*1.5)/2),
  17.               text=text, fill=0,
  18.               font=ImageFont.truetype('msyh.ttc', size=fontsize))
  19.     bottom_fontsize = (size-20)//len(bottomtext)
  20.     bottom_font = ImageFont.truetype('STHUPO.TTF', size=bottom_fontsize)
  21.     x, y = (size-bottom_fontsize*len(bottomtext))/2, size-bottom_fontsize*1.2
  22.     draw.text(xy=(x, y), text=bottomtext,
  23.               fill=0, font=bottom_font)
  24.     text_border(bottomtext, x, y-4,
  25.                 bottom_font, 0, (255, 255, 255))
  26.     im.thumbnail(result_size)
  27.     return im
复制代码
测试一下:
  1. text_img("鱼香茄子")
复制代码

ok,现在我们就已经可以或许给任何菜品生成图片了。但是菜品的名字那边来呢?我找到了一个网站,下面考虑爬一下它:

爬取菜品数据

网址是:https://m.meishij.net/caipu/
这个网站效果非常简单,一个简单的xpath即可获取到全部的菜品名称:

下面开始下载:
  1. from lxml import etree
  2. import requests
  3. req = requests.get("https://m.meishij.net/caipu/")
  4. html = etree.HTML(req.text)
  5. menu = html.xpath("//dl[@class='recipe_list']//a/text()")
  6. menu = list(set([_.strip(".") for _ in menu]))
  7. print(len(menu), menu[:10], menu[-10:])
复制代码
  1. 3744 ['排骨藕汤', '芋圆', '海鲜汤', '凉拌杏鲍菇', '三汁焖锅', '奶香玉米汁', '炒豆角', '茄子酱', '芒果糯米糍', '馒头'] ['清蒸茄子', '西兰花炒鸡', '老式蛋糕', '排骨年糕', '清炒丝瓜', '芋头蒸排骨', '木耳炒肉', '蚝油油麦菜', '麻辣鸡块', '荷叶饼']
复制代码
有了这些菜名,我们已经可以用来生成动图了。不过为了以后还可以或许学做菜,我们可以将菜名生存起来,要学做菜的时候呢打开网页:https://so.meishi.cc/?q=菜名,举行搜索。
生存菜名:
  1. with open("meau.csv", "w", encoding="u8") as f:
  2.     f.write("菜名\n")
  3.     for row in menu:
  4.         f.write(row)
  5.         f.write("\n")
复制代码
下面我们开始生成菜名动图:

生成菜名动图

3767多个菜名毕竟是太多,我们可以随意取30个菜名来生成动图:
  1. import random
  2. gif_list = random.choices(menu, k=30)
  3. print(gif_list)
复制代码
  1. ['蒸水蛋', '肉桂卷', '凉瓜炒蛋', '芝士焗红薯', '香蕉酥', '酸奶慕斯', '鸡蛋肠粉', '红油肚丝', '玉米鸡蛋饼', '酸辣豆腐汤', '萝卜炖牛腩', '苦瓜排骨汤', '腐竹拌芹菜', '西红柿炒土', '蒜蓉蒸茄子', '豆沙面包', '蘑菇炒肉', '清炒莲藕', '黑椒牛肉粒', '南瓜煎饼', '炒黄瓜', '杂粮馒头', '桃山皮月饼', '葱爆肉', '小炒牛肉', '豆瓣鲫鱼', '虾仁烩豆腐', '素馅饺子', '凉拌黄瓜', '砂锅鱼头']
复制代码
[code]PS:还是自己选好菜名,写死列表更好

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

帖子地址: 

回复

使用道具 举报

分享
推广
火星云矿 | 预约S19Pro,享500抵1000!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

草根技术分享(草根吧)是全球知名中文IT技术交流平台,创建于2021年,包含原创博客、精品问答、职业培训、技术社区、资源下载等产品服务,提供原创、优质、完整内容的专业IT技术开发社区。
  • 官方手机版

  • 微信公众号

  • 商务合作