您的位置:首页 > 编程语言 > Python开发

PIL去除写入字体的轮廓

2018-02-04 15:00 239 查看
转载请注明出处:http://blog.csdn.net/jinixin/article/details/79248842

别名:PIL去除写入字体的描边,PIL去除写入字体的黑边,Python制作透明背景图并去除写入字体的轮廓

问题

通过之前的一篇博客,简单介绍了Python使用PIL库制作透明背景图,并写上一行文字的方法。但随后发现生成的字体有着深色轮廓(如下图),如果将该图片附在淡色背景图上会显得十分格格不入。



有没有办法将这些深色轮廓去除呢?答案是肯定的,图中的文字也是由像素构成,可以考虑将那些深色像素替换成字体颜色。

准备

下面简单介绍用到的几个PIL库方法:

图像通道:

一幅完整的图像,是由多个通道组成的,它们共同作用产生了完整的图像。在RGB模式下就是指单独的红色R、绿色G、蓝色B这三通道。

1)Image.point(lut, mode=None)

通过传入的lookup表或一个函数来修改Image对象,返回产生的图像副本

lut参数:lookup表序列或者使用一个函数代替,该函数必须接收一个参数,该函数迭代处理图片中的每个像素,并将处理结果合并成一个新的图像(个人推荐用函数,因为没理解lookup表,逃~)

mode参数:定义了图像中关于像素的一些属性,默认和输入图像的属性保持一致

2)ImageColor.getrgb(color)

将一个字符串或十六进制表示的颜色转成RGB元组

3)Image.split()

将Image分成单个通道的图像并返回,如一个RGB图像将被分成三个新图像,每个新图像仅包含一个通道色彩(红、绿、蓝)。如果你仅需要一个通道,使用getchannel函数会更快



4)Image.merge(mode, bands)

将一系列通道图像合并成一个新的多通道图像并返回

mode参数:定义新图像的像素属性,详见这里

bands参数:含有一系列通道图像的序列,所有通道图像必须有着相同的大小

思路

1)先用image.split方法将RGBA图像分成R、G、B、A四个单通道图像;

2)接着使用image.point方法对R通道图像的每个像素都设成字体颜色的R值,并对G通道图像与B通道图像做同样处理,对掌管透明度的A通道图像不作处理,使之保持透明;

3)最后通过image.merge方法将2)中产生的所有通道图像合并成一个新图像,这时你会发现深色轮廓完全消失了。

处理后的效果图:



代码

#!/usr/bin/env python
# coding=utf-8

from PIL import Image, ImageDraw, ImageFont, ImageColor

font_color = '#E1FFFF'

image = Image.new(mode='RGBA', size=(400, 50))  # RGBA模式下没有color参数便是透明图片
draw_table = ImageDraw.Draw(im=image)
draw_table.text(xy=(0, 0), text=u'仰起脸笑得像满月', fill=font_color, font=ImageFont.truetype('./SimHei.ttf', 50))

fcolor_channel = ImageColor.getrgb(font_color)
r, g, b, a = image.split()                      # 将图像分成三个单通道图像

r = r.point(lambda x: fcolor_channel[0])        # 迭代处理R通道图像的所有像素,将它们设成字体颜色的R值
g = g.point(lambda x: fcolor_channel[1])
b = b.point(lambda x: fcolor_channel[2])

image = Image.merge('RGBA', (r, g, b, a))       # 合并多个通道图像成一个新图像

image.show()
image.save('满月.png', 'PNG')
image.close()


文中若有不当之处,还望大家包容和指出,感谢
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息