从零开始开发Python程序(五)—— 把文字排版成一张图片

承接上文,我们写了一个爬虫小程序,从网上抓取新闻信息:从零开始开发Python程序(四)—— 抓取每日早报新闻

目录

 

一、引入图片编辑库

二、用程序画一张图

三、新闻的内容文本处理

四、将新闻文本添加到图片中


一、引入图片编辑库

我们用PIL(Python Imaging Library)这个库来实现P图,PIL仅支持到Python 2.7,于是一群志愿者在PIL的基础上创建了兼容的版本叫Pillow,支持最新Python 3.x,又加入了许多新特性,所以,我们直接安装使用Pillow。执行以下脚本安装:

pip install pillow

 安装效果:

二、用程序画一张图

先体验一下,画出一张图片是什么感觉,然后再根据自己的喜好,把文字排版上去~

直接上代码,(代码#号后面的内容表示注释,便于理解,不会影响程序运行):


from PIL import Image, ImageDraw, ImageFont  # 引入图片,画图笔,图片字体三个库

img_1 = Image.new('RGB', (750, 2000), (255, 255, 255)) # 建一张新图,颜色用RGB,尺寸 750x2000,底色三个255表示纯白
draw = ImageDraw.Draw(img_1) # 创建一个画笔

header_position = (130,200) # 标题的横纵坐标位置
header_font = ImageFont.truetype('C:/Windows/Fonts/simkai.ttf', 55) # 标题的字体楷体,字号55
draw.text(header_position , '互联网日报', '#726053', header_font) #入参分别是坐标,文字内容,文字色号,文字字体

img_1.show() # 弹框展示图片

执行效果: 会弹出一张图片,上面用楷书写着’互联网日报‘ 

 

三、新闻的内容文本处理

这里我们要对新闻内容文字稍作处理,分析一下之前获取到的新闻内容,发现有几个小问题

 1. 内容中有一些没用的html标签,例如 <p><br/></p>我们要去掉

 2. 有一些空白的新闻,我们要过滤掉 例如 3、<br/>

 3. 我们在绘制图片的时候不支持整段文档的自动换行,这里要将文本分割成一行行的句子,再逐行写入图片中。

上代码: 

news_content = str(news_content) # 将html标签转成纯字符串
news_content = news_content.replace('<p>', "") # <p>标签替换成空字符串
news_content = news_content.replace('</p>', "") # </p>标签替换成空字符串
news_content = news_content.replace('<br/>', "\n")  # '<br/>'标签替换成系统换行符
news_content = news_content.splitlines()  # 按行分割,返回结果是一个数组,数组元素是单行的文字

import textwrap # 该库用于手动换行文字,接下来将手动限制每行字数不超过25字

news_wrap = [] # 准备一个数组来装我们的结果集
for line in news_content: # 循环遍历数组中的每行文字,line是临时变量,指代当前所循环到的文字
    if len(line) < 4:  # 左边有四个空格, len(line)表示计算该行的字数,小于4个字的就舍弃
        continue   # 左边有八个空格,
    elif len(line) < 25:   # 若字数大于4个且小于25个
        news_wrap.append(line)   # 添加到数组中
    else:    # 若字数大于25个字
        wrap = textwrap.wrap(line, 25) # 按每行25个字分割成数组
        news_wrap = news_wrap + wrap  # 拼到结果数组中
 print(news_wrap) # 分割后的数组打印出来看看

这部分涉及到内容格式化的的代码比较长,涉及到的知识点比较多;解释说明:

1. str(xxx) ,这个函数可以将其他数据格式,转换成纯字符串,便于进行字符串的查找替换处理

2. xxx.replace('a','b'), 这个函数在字符串中可以用,将字符串中的 a 替换成 b;

3. xxx.splitlines(), 这个函数将整段文字,按照换行符,分割成数组:

    例如: 上面这端话、按行分割后的结果就是 = [ '1.str(xxx)...', 'xxx.replace('a','b')...' , 'xxx.splitlines()']

4. for xx in xxx: 遍历循环,每次从xxx中取出一个元素进行处理

5. if xxx: 逻辑判断条件,满足该条件则进入冒号后紧跟着的代码块

6. elif xxx: 如果不满足上满的条件,但是满足这个条件,则进入

7. else: 如果都不满足,则进入

8. len(xx) 计算xx的长度,如果xx是一个字符串,则计算字符串的字数;len = lenght的缩写。

9. textwrap.wrap(xx,25); 将这个字符串分割成每行不超过25个字的数组。

执行效果: 数据格式是: [ 'xxx', 'xxx', 'xxx' , 'xxx' ] 

四、将新闻文本添加到图片中

创建图片并写入文字的程序步骤:

1. 引入图片、画笔、字体

2. 根据新闻行数,生成一个空白图片

3. 在图片上创建一个画笔

4. 指定写入文字的位置、字体、内容、颜色,然后从上往下逐行写入

5. 用一个变量记录当前写到图片的位置高度,每次画笔写入后,画笔的位置向下方移动特定的高度

6. 完成后展示、或保存图片

 上代码

from PIL import Image, ImageDraw, ImageFont  # 引入图片,画图笔,图片字体三个库
IMG_SIZE = (900, len(news_wrap) * 44) # 图片尺寸 900x新闻行数x每行行高
img_1 = Image.new('RGB',IMG_SIZE  , (255, 255, 255))  # 建一张新图,颜色用RGB,,底色三个255表示纯白
draw = ImageDraw.Draw(img_1)  # 创建一个画笔

header_position = (60, 30)  # 标题的横纵坐标位置
header_font = ImageFont.truetype('simkai.ttf', 55)  # 标题的字体楷体,字号55
draw.multiline_text(header_position, '互联网日报', '#726053', header_font)  # 入参分别是坐标,文字内容,文字色号,文字字体

current_height = 100
for line in news_wrap:
    if line.startswith('【'):
        news_font = ImageFont.truetype('simkai.ttf', 45)  # 标题的字体楷体,字号50
        draw.text((60, current_height + 30), line, '#726053', news_font)
        current_height += 80
    else:
        news_font = ImageFont.truetype('simkai.ttf', 30)  # 新闻字体30
        draw.text((60, current_height), line, '#726053', news_font)
        current_height += 40

img_1.show()  # 弹框展示图片
img_1.save('早报.jpg') # 保存成文件

解释一下

这里面的行高字体是我根据自己的想法排班的,没有一个定论

执行效果:如果图片会直接弹框展示,恭喜你已经完成了这部分的内容;字体、颜色排班可以根据自己的想法调整试试~

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值