python PIL使用记录

1.python PIL简介:

参考维基百科:

Python Imaging Library(缩写为PIL),是一个用于Python编程语言的免费库,它增加了对打开,操作和保存许多不同图像文件格式的支持。适用于Windows,Mac OS X和Linux。

项目地址:

指导书Handbook:

应用能力:

处理方法:
  • 像素操作;
  • 掩蔽和透明处理;
  • 图像过滤,例如模糊,轮廓,平滑或边缘查找
  • 图像增强,如锐化,调整亮度,对比度或颜色
  • 添加文本到图像等等。
支持格式:

目前,支持PPM,PNG,JPEG,GIF,TIFF和BMP。还可以创建新的文件解码器以扩展可访问的文件格式库。


2.项目中遇到的应用场景

python PIL改变图像的分辨率dpi

在项目中,遇到需要更改图像dpi的情况,比如常见dpi为72,想将其修改为96,可以使用以下代码:

from PIL import Image, ImageDraw, ImageFont

def change_pixel(inp_fn, out_fn=None, pixel=None):
	if out_fn is None:  # 设置输出的图像名称
		fn_flds = inp_fn.split('.')
        fn_flds[-2] += '_cp'
        out_fn = '.'.join(fn_flds)
    if pixel is None:  # 默认为72
        pixel = 72
    im = Image.open(inp_fn)  # 读取输入图像
    quality_score = 95
    im.save(out_fn, dpi=(pixel, pixel), quality=quality_socre)  # 保存图像,其输出图像out_fn的dpi会变成指定的像素。
    # 其中quality是保存的质量分数,取值范围为0~100,其值越大,质量越好,建议不超过95.
    return out_fn
修改完后:
从图中可以看到,其分辨率dpi已经从72修改为96。

python PIL resize修改图像的长宽

在项目中,遇到长宽比例不变,按照长度,或者宽度重新修改图像的尺寸,这种情况可以通过resize函数很好的解决,但是需要计算好相关但比例及真值。
以宽度为例子,比如一张图像的大小为300x375,想按照宽度重置为600,则可以用以下代码实现:

from PIL import Image, ImageDraw, ImageFont
import math

def resize_width(inp_fn, basewidth, out_fn=None):
    '''
    resize the image accodring to width|basewidth
    '''
    # 设置输出名称
    if out_fn is None:
       fn_flds = inp_fn.split('.')
       fn_flds[-2] += '_rsw'
       out_fn = '.'.join(fn_flds)
    # 读入图像
    im = Image.open(inp_fn)
    w, h = im.size  # 获得图像的尺寸
    # basewidth 是想要获得的宽度,计算缩放比例
    wpercent = (basewidth/float(w))
    # 计算缩放的长度,向上取整
    hsize = math.ceil((float(h)*float(wpercent)))
    # resize操作,设定为Image.ANTIALIAS:高质量下采样滤波器,抗锯齿形
    img = im.resize((basewidth, hsize), Image.ANTIALIAS)
    # 保存图像
    img.save(out_fn, quality=95)
    return out_fn
修改后:
可以看到,其宽度变为了600, 高度变为750。同理也可以以长度为基底,按照长度的缩放比例改变宽度的尺寸。

python PIL生成相应的背景颜色图

生成指定颜色,大小的背景图。指定颜色是通过一组三色值组合来实现,比如白色为(255,255,255),三个值分别表示红色,绿色和蓝色
代码如下:

from PIL import Image, ImageDraw, ImageFont

def gen_img(siez=None)
	if size is None:
		size = 400
	# 生成大小为400x400RGBA是四通道图像,RGB表示R,G,B三通道,A表示Alpha的色彩空間
	image = Image.new(mode='RGBA', size=(400, 400), color=(255, 55, 55))
	# ImageDraw.Draw 简单平面绘图
	draw_table = ImageDraw.Draw(im=image)
	# 直接显示图片
	image.show() 

输出结果如下:

代码不是很长,下面简单解释代码中用到的几个方法:
  • PIL.Image.new(mode, size, color=0):

    • 功能:通过给定的mode创建指定大小的image对象;
    • mode参数:定义了图像中关于像素的一些属性。比较常见的有:黑白图像L,真彩色RGB,带透明度的真彩色RGBA等;
    • size参数:以像素为单位指定图片的长与宽,tuple形式;
    • color参数:指定图片的背景色。当图像模式为RGBA时,若不指定该参数,默认便是透明背景;
  • PIL.ImageDraw.Draw(im, mode=None):

    • 功能:创建一个对象用于在image对象上进行作画;
    • im参数:已创建的image对象;
    • mode参数:定义了图像中关于像素的一些属性。若未给定,将与传入的image对象的mode参数保持一致;
  • PIL.ImageDraw.ImageDraw.text(xy, text, fill=None, font=None, direction=None)

    • 功能:在图片指定位置写一行文本,多行文本需要使用multiline_text方法;
    • xy参数:指定文本距左上角的位置,tuple形式;
    • text参数:文本内容;
    • fill参数:文本颜色,支持英文单词与十六进制表示法;
    • font参数:字体对象,一般通过ImageFont模块构建,用于指定字体文件位置与字体大小;
    • direction参数:文本内容方向,需要libraqm支持;

python PIL 图像合成

在项目中,遇到将两张图像进行叠加,分别给定叠加的具体位置,比如:
图像1:logo背景图和图像2:模特图

现在,将其叠加到一起,代码如下:
from PIL import Image, ImageDraw, ImageFont

def img_over(inp_fn, logo, x, y, out_fn=None):
        '''
        insert the img into logo background
        '''
        # 设置输出图像名称
        if out_fn is None:
            fn_flds = inp_fn.split('.')
            fn_flds[-2] += '_ov'
            out_fn = '.'.join(fn_flds)
        # 读入两张图像
        img = Image.open(inp_fn)
        img_logo = Image.open(logo)
        # 设置背景大小
        background = Image.new("RGB", img_logo.size, (255, 255, 255))  	  
        # convert RGBA into RGB
        background.paste(img_logo, mask=img_logo.split()[3])
        img_logo = background
        # 将输入图粘贴到背景图上,x,y指定粘贴起始位置
        img_logo.paste(img, (x, y))  # over
        # 保存
        img_logo.save(out_fn, quality=95)
        return out_fn

结果如下:

python PIL 使用遇到的问题

在项目中,常见的一个问题是:

OSError: cannot write mode RGBA as JPEG

无法将RGBA格式的图像保存为JPEG格式的图像,因此,在进行保存之前,要进行转换之后再进行保存。
常用的修改方法:
1.将四通道转换为三通道

from PIL import Image
file_in = "test.png"
img = Image.open(file_in)
file_out = "test2.bmp"
print len(img.split())  # test
if len(img.split()) == 4:
    #prevent IOError: cannot write mode RGBA as BMP
    r, g, b, a = img.split()
    img = Image.merge("RGB", (r, g, b))
    img.save(file_out)
else:
    img.save(file_out)
  1. 借用背景图将其转换为三通道图
img = Image.open(inp_fn)
# 设置背景大小
background = Image.new("RGB", img.size, (255, 255, 255))  	  
# convert RGBA into RGB
background.paste(img, mask=img.split()[3])
img = background
img.save("new_jpg", quality=95)

此时的img即为三通道图,这样就可以正常保存。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

uncle_ll

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值