简述
2018年的三月份写过一篇:《小猪的Python学习之旅 —— 18.Python微信转发小宇宙早报》,从一开始
手动转发别人发的新闻早报,到编写脚本到自动转发。然后毕竟这个是别人整理的,并不能保证准时,很多
时候早报变成了午报,然后还有存档问题,每次想看之前的早报就,都要微信搜聊天记录。啧啧,我琢磨着,
要不自己来整理早报。于是偷偷开始手动去整理早报,然后发在公号「抠腚男孩」上:

毕竟自己整理的,不确定看官能不能接受,得找几个小火汁来验证下下~

然后,把我整理的日报,套模板,改下日期,丢到童鞋群里看看他们有木有发现,测试两天后~

行吧,我就发吧,接下来简单说下每天发早报的流程。

1.制作当天早报的封面图
2.浏览新华社,i黑马,第一财经周刊等新闻站点,采集有趣的新闻,复制下标题。
3.把复制的标题粘贴到文本编辑器中,凑够15条新闻。
4.登录微信公众平台,打开昨天的文章,复制样式,粘贴,然后把今天的内容填进去。

接着检查下,没什么问题,就发布了。一开始,每天要耗费将近一个小时的时间来完成这件
事情,每天的摸鱼时间这么宝贵,花一个小时来做这件事情,显得有些得不偿失。作为一个
**勤(lan)奋(duo)**的开发仔,肯定要想办法来优化下,最好的结果就是:发早报完全自动化~

当然,也是想想而已,有读者可能好奇,为啥标题是80%,那么剩下的20%是什么?

答:15%是新闻的过滤,筛选有意思的新闻标题,这一步其实可以优化,最简单的就是,直接爬热搜
或者评论多的新闻标题,但是这样莫得灵魂,我更倾向于训练一个机器人,让他自动去筛选标题。
但是目前还不会这些东西,所以先搁一搁咯,还得手动去筛选~
剩下的5%是把早报发表到公号上,其实也可以自动化,通过selenium写个脚本自动点点点
就好了,不过个人感觉意义不大,而且我习惯发出去之前还需要预览下,确认内容
无误后才发送,毕竟文章发布后只能改标题,不能修改内容。
说下我目前想达到的一个形态吧:

1.编写脚本批量生成微信的封面图。
2.编写爬虫定时去爬取新闻,保存到本地数据库中。
3.编写接口,包括获取当天采集到的新闻,加入到新闻筛选池等。
4.编写用来筛选新闻的APP,利用上班坐地铁的时间快速筛选当天的新闻标题。
5.编写一键生成统一样式的早报文章的脚本。
6.编写一键生成当天新闻详情页面的脚本。
7.复制粘贴生成的样式文章,填写标题,发布者,在阅读原文中添加当天新闻详情页面的url,完成发布。
8.编写微信机器人,定时(暂定10点),拉取早报进行文本处理后,自动转发到相关的群。

好吧,大概的路线就这样,本节先从制作早报封面图开始**优(偷)化(懒)**吧。

1.封面图的制作过程
先来看看我每天的早报封面图吧,是介样的:

组成部分:背景图(900*383)+ 大标题(52px) + 二级标题(44px)
接着缩下我是制作这种封面图的流程:

1.平时闲着没事逛下一些壁纸的APP或者站点,觉得好看的就保存下来。
2.打开Pixelmator Pro新建一个900*383的模板,把图片拖进去,调节图片大小直到图片的宽度和模板的宽度相等。
3.接着移动调整缩放后的图片,直到自己喜欢位置。
4.依次添加大小标题,调整居中。
5.合并图层,裁剪。
6.导出成jpg文件。

为了让你们感受这个流程,我大概录了个Gif演示下,实际操作耗时远比这个久(7,8分钟的样子)。

每天如机器搬重复着这样的操作,多呆哦~然后,我竟然坚持了60+天(┬_┬);
着实需要一个脚本,把我从这种繁冗的工作中解脱出来。
读者可能对图源感兴趣,我一般喜欢直接保存壁纸APP里精选的靓图,
当然也可以自行爬取一些壁纸站点。另外,我发现,有些长图,其实
可以裁剪成几份来作为多期的封面,比如这样的图:

分割成两个,挺好看的。

感觉像像集卡一样,有点意思。

2.提取图片处理的流程
先来提取下图片处理的流程:

图片缩放:保持长宽比例不变进行缩放,直到宽为900px为止。
图片裁剪:先计算图片可以裁剪成多少份,以图片中间为基准裁剪,计算Y轴偏移,每个图片的坐标。
图片加字:对裁剪后的图片依次添加大小标题。

3.材料准备
行吧,处理流程说了,说下用到的Python库,直接通过pip命令安装即可:
(主要使用opencv来进行图片处理,pillow即PIL库)
pip install numpy
pip install opencv-python
pip install pillow
复制代码4.图片缩放
保持长宽比,设置为900px,我们通过opencv提供的imread()方法来获取一个图片对象,然后进行
相关操作。先获取一波高和宽度
import cv2

img = cv2.imread(‘1.jpg’)
(h, w) = img.shape[:2]
print(h, w)

输出结果:956 1080

复制代码如果你想把图片显示出来,可以直接调用imshow()方法:
cv2.imshow(‘image’, img) # 参数依次为:窗口名称(窗口不能重名),读入的图片。
复制代码上述的代码,运行后会发现窗口一闪而过,可以调用waitKey()让窗口不关闭
cv2.waitkey() # 想窗口一直不关闭,可以不填参数或填0;也可以指定一个等待时间(单位毫秒)
# 在一个时间段内,等待用户按键触发关闭,如果一直不按键,到了时间会自动关闭。
复制代码但是,这里其实隐藏着一个小坑:如果你的图片是中文文件名或文件路径包含中文,调用imread会报错,比如:
img = cv2.imread(‘测试.jpg’)
cv2.imshow(‘img’, img)
cv2.waitKey()
复制代码运行结果:

同样调用imwrite()方法也是无法生成带有中文路径的图片的,可以自行编写两个函数来解决:
def cv_imread(file_path):
cv_img = cv2.imdecode(np.fromfile(file_path, dtype=np.uint8), -1)
return cv_img

def cv_imwrite(img, file_path):
cv2.imencode(’.jpg’, img)[1].tofile(file_path)
复制代码行吧,能获取到宽高了,接着调用opencv提供的resize()方法调整图片的尺寸,参数依次为:
图片,宽高元组,还有一个可选参数:interpolation插值方法,默认使用INTER_LINEAR
双线性插值,其他的还有:INTER_NEAREST,INTER_AREA,INTER_CUBIC,INTER_LANCZOS4。
import cv2
import numpy as np

def cv_imread(file_path):
cv_img = cv2.imdecode(np.fromfile(file_path, dtype=np.uint8), -1)
return cv_img

def cv_imwrite(img, file_path):
cv2.imencode(’.jpg’, img)[1].tofile(file_path)

img = cv_imread(‘测试.jpg’)
(h, w) = img.shape[:2]
print(“缩放前的尺寸:”, img.shape[:2])
res = cv2.resize(img, (900, round(h * (900 / w))))
print(“裁剪后的尺寸:”, res.shape[:2])
复制代码运行结果:
缩放前的尺寸: (956, 1080)
缩放后的尺寸: (797, 900)
复制代码5.图片裁剪
缩放完,接着就到裁剪了,先是计算图片能裁剪成几张:
crop_pic_count = int(ch / 383)
print(“图片可以裁剪为:%d张” % crop_pic_count)

输出结果:图片可以裁剪为:2张

复制代码接着是裁剪图片,可以通过:图片对象[y轴起始坐标:y轴终点坐标, x轴起始坐标:x轴终点坐标],来裁剪。
所以,我们要计算每个裁剪区域的对应的坐标方位。另外,这里还要考虑一个偏移,以中间位置为基准进行
裁剪,这样感觉会好一点。给个加偏移和不加偏移裁剪后的对比图吧:

so,我还是倾向于加偏移,计算偏移也很简单,直接拿高对383进行求余,然后除以2。
start_y = int(ch % 383 / 2)
复制代码接着根据能切成的图片张数,计算怎么裁剪
for i in range(0, crop_pic_count):
crop_img = res[383 * i + start_y: 383 * (i + 1) + start_y, 0:900]
cv_imwrite(crop_img, ‘剪切图%d.jpg’ % (i+1))
复制代码裁剪后的图片:

6.图片加字
行吧,图片也裁剪好了,接着就是图片加字了,可以通过opencv提供的putText()添加文字,
参数依次为: 图像,文字内容, 坐标 ,字体,大小,颜色,字体厚度。
img = cv_imread(‘剪切图0.jpg’)
cv2.putText(img, ‘Test’, (50, 300), cv2.FONT_HERSHEY_SIMPLEX, 1.2, (255, 255, 255), 2)
cv2.imshow(‘image’, img)
cv2.waitKey()
复制代码运行结果如下:

加字成功,挺简单的,是吧?但是,如果你添加的文字不是字母或数字,而是中文的话,那么恭喜,黑人问号~

原因是:opencv自带的putText函数无法输出utf8类型的字符,因此无法将中文打印到图片上。
两个解决方法:

方法一:利用另一个freetype库,将字符解码转码,不过有点繁琐。
方法二:利用pillow库里ImageDraw类的text函数绘制中文,先从成cv2转PIL格式,加完中文再转回cv2格式输出。

这里采用的是方法二,text函数的参数:起始坐标元组,文字内容,字体,颜色。
问题来了,怎么确定绘制文字的起始坐标?

答:如果你要程序算,挺麻烦的,文字宽度怎么获取,既然图片尺寸固定,文字长度不变,为何不取巧一下呢?
直接在Pixelmator Pro上把文字拖好,然后复制下坐标,不就好了~

另外,这里笔者用的字体是 苹果-简,常规体,可以自行下载,记得把字体文件名改成英文文件名,
不然,会读取不到字体。好的,撸代码试试:
img = cv_imread(‘剪切图0.jpg’)

将图片从OpenCv格式转为PIL格式

img_pil = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))

加载字体(字体文件名,字体大小)

title_font = ImageFont.truetype(‘apple-simple.ttf’, 52)
date_font = ImageFont.truetype(‘apple-simple.ttf’, 44)

绘制文字的位置

title_pos = (236, 110)
date_pos = (338, 192)

绘制内容

title_content = u"『抠腚早报速读』"
date_content = u"第190111期"

绘制

draw = ImageDraw.Draw(img_pil)
draw.text(title_pos, title_content, font=title_font, fill=(255, 255, 255))
draw.text(date_pos, date_content, font=date_font, fill=(255, 255, 255))
img_open_cv = cv2.cvtColor(np.asarray(img_pil), cv2.COLOR_RGB2BGR)
cv_imwrite(img_open_cv, “加字后.jpg”)
复制代码接着看下输出的图片:

啧啧啧,完美,到此自动裁剪生成一个早报封面的脚本就完成啦,接下来我们来补全和完善下我们的程序。
7.代码补全完善
就是加了循环,一些小逻辑,比较简单,注释也比较清晰,就不叨逼叨了,直接上完整代吧:

-- coding: utf-8 --

import os
import cv2
import numpy as np
import time
from PIL import Image, ImageDraw, ImageFont
from datetime import datetime, timedelta
import shutil

pic_source_dir = os.path.join(os.getcwd(), “news_pic_source\”) # 原图路径
pic_crop_dir = os.path.join(os.getcwd(), “news_pic_crop\”) # 裁剪后的图片路径
pic_font_dir = os.path.join(os.getcwd(), “news_pic_font\”) # 加字后的图片路径
start_date = “20190112” # 绘制图片的其起始日期

判断文件夹是否存在,不存在则新建

def is_dir_existed(path, mkdir=True):
if mkdir:
if not os.path.exists(path):
os.makedirs(path)
else:
return os.path.exists(path)

opencv读取中文路径名会乱码

def cv_imread(file_path):
cv_img = cv2.imdecode(np.fromfile(file_path, dtype=np.uint8), -1)
return cv_img

opencv写入中文路径名会乱码

def cv_imwrite(img, file_path):
cv2.imencode(’.jpg’, img)[1].tofile(file_path)

把原图裁剪为多个小图(900*383)

def crop_little_pic(pic_path):
img = cv_imread(pic_path)
(sh, sw) = img.shape[:2]
# 将图片的宽设置为900,高则按比例缩放
res = cv2.resize(img, (900, round(sh * (900 / sw))))
# 获取缩放后的高和宽,判断图片可裁剪的张数
(ch, cw) = res.shape[:2]
crop_pic_count = int(ch / 383)
# 计算Y轴偏移
start_y = int(ch % 383 / 2)
# 根据图片的张数来决定怎么裁剪
for i in range(0, crop_pic_count):
crop_img = res[383 * i + start_y: 383 * (i + 1) + start_y, 0:900]
cv_imwrite(crop_img, os.path.join(pic_crop_dir, str(int(round(time.time() * 1000))) + ‘.jpg’))

绘制文字

def draw_text(pic_path, date):
img = cv_imread(pic_path)
# 将图片从OpenCv格式转为PIL格式
img_pil = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
# 加载字体(字体文件名,字体大小)
title_font = ImageFont.truetype(‘apple-simple.ttf’, 52)
date_font = ImageFont.truetype(‘apple-simple.ttf’, 44)
# 绘制文字的位置
title_pos = (236, 110)
date_pos = (316, 192)
# 绘制内容
title_content = u"『抠腚早报速读』"
date_content = u"第%s期" % date[2:]
# 绘制
draw = ImageDraw.Draw(img_pil)
draw.text(title_pos, title_content, font=title_font, fill=(255, 255, 255))
draw.text(date_pos, date_content, font=date_font, fill=(255, 255, 255))
img_open_cv = cv2.cvtColor(np.asarray(img_pil), cv2.COLOR_RGB2BGR)
cv_imwrite(img_open_cv, os.path.join(pic_font_dir, date[2:] + ‘.jpg’))

遍历获得某类文件路径列表

def fetch_file_path(path, file_type):
file_list = []
f = os.listdir(path)
for i in f:
if i.endswith(file_type):
file_list.append(os.path.join(path, i))
return file_list

构造生成日期列表

def init_date_list(begin_date, count):
d_list = []
begin_date = datetime.strptime(begin_date, “%Y%m%d”)
end_date = datetime.strptime((datetime.now() + timedelta(days=count)).strftime("%Y%m%d"), “%Y%m%d”)
while begin_date <= end_date:
date_str = begin_date.strftime("%Y%m%d")
d_list.append(date_str)
begin_date += timedelta(days=1)
return d_list

if name == ‘main’:
is_dir_existed(pic_source_dir)
while True:
choice = input(
“%s\n请输入你想进行的操作\n1.进行图片裁剪\n2.图片加字\n3.清空裁剪文件夹\n4.清空加字文件夹\n5.退出程序\n%s\n” % (’=’ * 32, ‘=’ * 32))
if choice == ‘1’:
is_dir_existed(pic_crop_dir)
pic_path_list = fetch_file_path(pic_source_dir, “.jpg”)
if len(pic_path_list) == 0:
print(“原图文件夹中无图片,请先添加图片!”)
else:
print(“开始批量裁剪…”)
begin = datetime.now()
for pic in pic_path_list:
crop_little_pic(pic)
end = datetime.now()
print(“批量裁剪完毕,生成图片:%d张,耗时:%s秒” % (len(fetch_file_path(pic_crop_dir, “.jpg”)), (end - begin).seconds))
elif choice == ‘2’:
is_dir_existed(pic_font_dir)
crop_path_list = fetch_file_path(pic_crop_dir, “.jpg”)
date_list = init_date_list(start_date, len(crop_path_list) + 1)
if len(crop_path_list) == 0:
print(“裁剪文件夹中无图片,请先生成裁剪图片!”)
else:
print(“开始批量加字…”)
begin = datetime.now()
print(len(crop_path_list), len(date_list))
for i in range(len(crop_path_list)):
draw_text(crop_path_list[i], date_list[i])
end = datetime.now()
print(“批量加字完毕,处理图片:%d张,耗时:%s秒” % (len(fetch_file_path(pic_font_dir, “.jpg”)), (end - begin).seconds))
elif choice == ‘3’:
if is_dir_existed(pic_crop_dir, False):
shutil.rmtree(pic_crop_dir)
print(“文件夹删除成功!”)
else:
print(“文件夹不存在,删除失败~”)
elif choice == ‘4’:
if is_dir_existed(pic_font_dir, False):
shutil.rmtree(pic_font_dir)
print(“文件夹删除成功!”)
else:
print(“文件夹不存在,删除失败~”)
elif choice == ‘5’:
exit(“退出程序~”)
else:
print(“错误序号,请确认后重新输入!!!”)
复制代码执行前,先准备一波图片原图,这里准备了:

接着运行一波代码,运行后依次键入1,2进行裁剪和加字:

啧啧,94张原图生成了243张封面图,而且,只花了十几秒,打开生成的文件夹看一波:

都生成到9月份了,2333,真人生苦短,我用Python,此处应该有掌声~

另外前几天写了个脚本是采集一堆视频第一帧然后进行处理的,赶脚有同学会需要,把核心代码也贴下把~

截取视频的第一帧

def fetch_video_first_frame(path_list):
for mp4 in path_list:
cap = cv2.VideoCapture(mp4)
if cap.isOpened():
ret, im = cap.read()
cv2.imencode(’.jpg’, im)[1].tofile(
os.path.join(pic_source_output_dir, mp4.split("\")[-1]).replace(“mp4”, “jpg”))
cap.release()

原文链接

https://juejin.im/post/5c37100f6fb9a049fd100cae

服务推荐

  • 私密代理ip
  • 隧道代理ip
  • 微信域名拦截检测服务
  • 微信域名在线拦截检测工具
  • 微信域名在线批量拦截检测工具

偷个懒,公号抠腚早报80%自动化——1.批量生成微信封面图相关推荐

  1. 偷个懒,公号抠腚早报80%自动化——5.意思意思撸个APP收下尾

    0x1 简述 终于来到本系列的最后一节咯,本节撸个早报APP来调用下上节编写的接口~ 写完这个系列都有种自己是「全栈」工程师的错觉了~ 0x2 产品原型设计环节 APP的功能虽说比较简单,但是竟然说了 ...

  2. 偷个懒,公号抠腚早报80%自动化——2.手撕爬虫定时爬新闻

    简述 在上一节偷个懒,公号抠腚早报80%自动化--1.批量生成微信封面图中,我们利用opencv库 与PIL库生成半年分量的微信封面图,每次发布直接选图,美滋滋.按照剧本,本节我们的目标是: 编写爬虫 ...

  3. 偷个懒,公号抠腚早报80%自动化——4.用Flask搭个简易(陋)后台

    简述 在上一节「偷个懒,公号抠腚早报80%自动化--3.Flask速成大法」中,快速地把 Flask的基本语法撸了一遍,本节直接开冲,用Flask来写下抠腚男孩的后台. PS:笔者没有真正参加过前后端 ...

  4. 偷个懒,公号抠腚早报80%自动化——3.Flask速成大法

    简述 在上一节中,我们编写了抓取新闻的爬虫脚本,每天早上八点定时抓取新闻保存到 MySQL数据库中.直接用DataGrip连下数据库,就可以查看爬取到的新闻了.不过, 并不是我们想要的最终形态.我希望 ...

  5. 中国第一代白手起家创业者联想柳总等格局,附联想国企变民企史(赞赏后公号回复“联想格局”下载PDF典藏资料)

    中国第一代白手起家创业者联想柳总等格局,附联想国企变民企史(赞赏后公号回复"联想格局"下载PDF典藏资料) 原创: 秦陇纪 科学Sciences 今天 科学Sciences导读:中 ...

  6. 深度学习的几何观点:1流形分布定律、2学习能力的上限。附顾险峰教授简历(长文慎入,公号回复“深度学习流形分布”可下载PDF资料)

    深度学习的几何观点:1流形分布定律.2学习能力的上限.附顾险峰教授简历(长文慎入,公号回复"深度学习流形分布"可下载PDF资料) 原创: 顾险峰 数据简化DataSimp 今天 数 ...

  7. 密码学历史及近40年人物技术里程碑(公号回复“密码学”下载PDF资料,欢迎转发、赞赏、支持科普)

    密码学历史及近40年人物技术里程碑(公号回复"密码学"下载PDF资料,欢迎转发.赞赏.支持科普) 原创: 秦陇纪 科学Sciences 今天 科学Sciences导读:密码学是研究 ...

  8. 自然语言理解的机器认知形式系统(公号回复“黄培红/认知理解”下载PDF资料,欢迎赞赏转发支持)

    自然语言理解的机器认知形式系统(公号回复"黄培红/认知理解"下载PDF资料,欢迎赞赏转发支持) 原创: 黄培红 数据简化DataSimp 今天 数据简化DataSimp导读:本文是 ...

  9. 你在孩子身上偷的懒,终将会变成最大的遗憾

    全世界只有3.14 % 的人关注了 青少年数学之旅 我们来看一个非常有趣的统计: 2007年-2016年全国高考状元父母职业统计 最优秀的孩子大多数出自教师家庭. 很家长说,教师有着和孩子一样的寒暑假 ...

最新文章

  1. 围观阿里云最会赚钱的人!价值2万元邀请码不限量发送
  2. 帮你梳理springboot所有常用注解
  3. obs virtual camera
  4. (2) java项目中用redis
  5. excel range 判断日期型_为什么精英都是Excel控?
  6. java中字节码_Java字节码执行图示
  7. HTML5语义元素的使用
  8. poj3233Matrix Power Series
  9. linux中^]是如何输出的
  10. 解决 Error: Table './db_name/table_name' is marked as crashed and last (automatic?) repair
  11. 如何设置NeoFinder在共享网络中的目录数据库
  12. TM2008预览版试用 速度快完美兼容Vista
  13. shiro身份认证(HelloWorld)
  14. Ubuntu卸载历程,包含重启进入grub解决方案
  15. 沉浸其境,共赴云栖数智硬核美学
  16. step5.游戏窗口的初始化
  17. android 手机号码去重,微信电话本和qq通讯录有什么不同?微信电话本常见问题汇总...
  18. 液晶面板价格继续下跌,中国面板企业能否盈利面临考验
  19. 蓝桥杯 提高题 母牛的故事
  20. 北航计算机考博经验,考博经验——说说我北邮北航考博经历

热门文章

  1. Jupyter Notebook的16个超棒插件!
  2. www.1188.com劫持IE,baidu工具条不甘落后
  3. 一个卡拉OK效果的自定义歌词控件
  4. Google 中国在首页为 5.12 地震遇难者祈祷
  5. 本周AI热点回顾:GPT-3论坛跟帖灌水一周无人发现; 潘建伟院士高徒陆朝阳获美国物理学会量子计算奖
  6. Imail邮件服务器的使用
  7. 操作系统?我重新设置虚拟内存大小并更改了它的位置
  8. html鼠标样式形状优化,鼠标箭头总变成放大镜样式,怎么恢复?
  9. 试一下JAVAMAIL
  10. 基于python实现利用DEM数据计算坡度、坡向