Python的Pillow(图像处理库)的一些学习笔记

2024-06-08 13:28

本文主要是介绍Python的Pillow(图像处理库)的一些学习笔记,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Python的Pillow库是一个非常强大的图像处理库。

安装Pillow库:

在终端或命令行中输入以下命令来安装Pillow:

pip install pillow 

升级库:

pip install pillow --upgrade 

一些基础的应用 

1、图像文件方面的:

打开文件

1)直接打开文件:

这种方式是最常见的直接打开图片文件的方法,以文件路径作为参数,PIL 库会自动打开并加载图片。

from PIL import Image
import ioim1 = Image.open('d:\\mask3\\type_ARGB32.png')   # 直接打开
2) 从文件对象中打开:

这种方式是先使用 open() 函数以二进制只读模式打开文件,然后将文件对象传递给 PIL 中的 Image.open() 方法进行加载并创建 Image 对象。

with open("d:\\mask3\\type_ARGB32.png", "rb") as f:im2 = Image.open(f)
3) 将文件内容读取为内存中的字节流后再打开:

这种方式先将文件内容读取为内存中的字节流(通过 io.BytesIO() 创建字节流对象并使用 read() 方法读取文件内容),然后再通过 Image.open() 打开这个内存中的字节流来创建 Image 对象。

with open("d:\\mask3\\type_ARGB32.png", "rb") as f:image_memory = io.BytesIO(f.read())im3 = Image.open(image_memory)
打开文件时需要注意文件的生命周期:

看代码:

from PIL import Image
import iowith open("d:\\mask3\\type_ARGB32.png", "rb") as f:im2 = Image.open(f)im2.show()# 出错:ValueError: seek of closed file

 在这里,通过 Image.open() 直接打开了图片文件并使用 with 语句来确保资源正确关闭,创建了图片对象 im2。然而,在 with 语句块外部访问 im2.load() 操作时,虽然图片对象仍然存在,但由于已超出 with 语句的范围,此时访问图片对象已经不再可用,导致失败。

with open("d:\\mask3\\type_ARGB32.png", "rb") as f:im2 = Image.open(f)im2.show()

 改成如上后就可以正确执行了。

类似的例子:

from PIL import Image
import iof= open("d:\\mask3\\type_ARGB32.png", "rb")
im2 = Image.open(f)
f.close()im2.show()

由于文件已经被手动关闭了,PIL 试图从已关闭的文件对象中读取图像数据。所以会出错。如果正常运行,需要将im2.show()挪到f.close()前面。

或者将文件存储在内存中,也可以不受文件周期的影响: 

import iofrom PIL import Imagef = open("d:\\mask3\\type_ARGB32.png", "rb")
image_memory = io.BytesIO(f.read())
im3 = Image.open(image_memory)
f.close()im3.show()

或者在关闭文件之前使用load()将图像数据加载到内存中的图像对象中:

from PIL import Imagef = open("d:\\mask3\\type_ARGB32.png", "rb")
im2 = Image.open(f)
im2.load()
f.close()im2.show()

获取某一坐标点(x,y)的像素值getpixel()

pixel = im.getpixel((100,100))

获取图像的窗口位置和大小getbbox()

bbox = im.getbbox()

 图像的特性(格式、大小、宽高、透明度)

from PIL import Image# 读取硬盘中的图像文件
file_path = 'd:\\mask3\\type_ARGB32.png'
im = Image.open(file_path)print(im.size)   # 图像几何尺寸:(1920, 1080)
print(im.mode)   # 图像模式:RGBA
print(im.format)  # 图像格式:PNG
print(im.width, im.height)  # 图像宽高:1920 1080
print(im.has_transparency_data)  # 是否有透明度: True

图像的字节数据tobytes()

img_bytes = im.tobytes()

获取图像所有的通道getbands()

bands = im.getbands()

getbands() 返回的值:灰度图的通道:('L',),二值黑白('1',),彩图('R', 'G', 'B')或('R', 'G', 'B', 'A')

获取指定通道的图像getchannel()

R_channel = im.getchannel("R")

获取图像中每个像素的像素值数据getdata()

data = R_channel.getdata()

tobytes()和getdata()的区别

  1. tobytes() 方法:

    • tobytes() 方法用于将图像数据转换为原始字节序列。
    • 返回的是包含整个图像像素数据的字节序列,其中每个像素可能包含多个通道的值。
    • 如果图像是多通道的,tobytes() 方法将返回按照图像模式中通道的顺序排列的像素值序列。
    • 适用于需要处理原始图像数据的情况,比如图像数据的存储、传输等。
  2. getdata() 方法:

    • getdata() 方法用于获取图像中每个像素的像素值数据。
    • 返回的是图像中每个像素的像素值数据,通常是一个包含像素值的序列,每个像素值可能包含多个通道的值。
    • 如果图像是多通道的,getdata() 方法将返回像素值按照通道顺序组织的序列,而不是一个连续的字节序列。
    • 适用于需要逐像素访问图像数据的情况,比如进行像素级操作、分析等。

总的来说,tobytes() 返回的是整个图像的原始字节序列,而 getdata() 返回的是图像中每个像素的像素值数据序列。根据具体的需求,你可以选择使用这两个方法来获取和处理图像数据。

demo:

用画图软件画一个 2*2像素的bmp文件,如图:

 图像文件总共有4个像素,

第一行:(255,0 , 0)  (255,255,255)

第二行:(255,0 , 0)  (255,255,255)

from PIL import Imagefile_path = 'd:\\mask3\\2020bmp.bmp'
im = Image.open(file_path)   # 打开文件
img_bytes = im.tobytes()   # 图像的字节数据
img_datas = im.getdata()   # 图像的像素值数据print('img_bytes=',list(img_bytes))   # img_bytes= [255, 0, 0, 255, 255, 255, 255, 0, 0, 255, 255, 255], 返回的是整个图像的原始字节序列
print('img_datas=',list(img_datas))   # img_datas= [(255, 0, 0), (255, 255, 255), (255, 0, 0), (255, 255, 255)], 返回的是图像中每个像素的像素值数据序列

再比如:

from PIL import Imagefile_path = 'd:\\mask3\\2020bmp.bmp'
im = Image.open(file_path)   # 打开文件B_channel = im.getchannel("B")   # 获取指定通道的图像
img_bytes = B_channel.tobytes()   # 图像的字节数据
img_datas = B_channel.getdata()   # 图像的像素值数据print('img_bytes=',list(img_bytes))   # img_bytes= [0, 255, 0, 255]
print('img_datas=',list(img_datas))   # img_datas= [0, 255, 0, 255]

由于是单通道数据,所以上述两个函数的返回结果是相同的。

设置像素值putdata()

使用像素值数据:
from PIL import Imagefile_path = 'd:\\mask3\\2020bmp.bmp'
im = Image.open(file_path)
# 给定的像素值数据序列
img_bytes = im.getdata()# 创建新的图像对象,这里创建一个大小为 2x2 的 RGB 模式图像
new_image = Image.new('RGB', (2, 2))  # 使用 RGBA 模式是因为给定的像素值数据包含 Alpha 通道# 将像素值数据复制到新图像对象中
new_image.putdata(img_bytes)# 保存新图像对象到文件中
new_image.save('new_image.BMP')print("新图像文件已保存成功!")
使用字节数据:
from PIL import Imagefile_path = 'd:\\mask3\\2020bmp.bmp'
im = Image.open(file_path)# 分离每个通道的像素值数据
R_channel, G_channel, B_channel = im.split()# 重新组合像素值数据为 RGB 格式
new_bytes = list(zip(R_channel.getdata(), G_channel.getdata(), B_channel.getdata()))# 创建新的图像对象,大小为 2x2 的 RGB 模式
new_image = Image.new('RGB', (2, 2))
new_image.putdata(new_bytes)# 保存新图像对象到文件中
new_image.save('new_image.BMP')print("新图像文件已保存成功!")

2、编辑和显示方面

显示show()

from PIL import Image# 打开文件,Windows系统可以设置默认的打开程序,比如画图
with Image.open('d:\\mask3\\type_ARGB32.png') as im:im.show()

请注意,这是只读方式的,即使在软件中对图像进行了编辑也无法直接保存 ,如果需要保存可以使用“另存为”。

加载load()和seek()

将图像文件加载到内存中,以供后续的处理和操作。

load()
from PIL import Imagef = open('d:\\mask3\\type_ARGB32.png', "rb")
im2 = Image.open(f)
im2.load()
f.close()im2.show()

 对于单帧图片,可以在load()之后将文件关闭,然而对于多帧的图像格式,比如gif,就要等load()之后所有的操作完成后才能将文件关闭。比如下面的代码就会报错:

from PIL import Imagef = open('d:\\mask3\\2.gif', "rb")
im2 = Image.open(f)
im2.load()
f.close()im2.show()

 需要改成:

from PIL import Imagef = open('d:\\mask3\\2.gif', "rb")
im2 = Image.open(f)
im2.load()
im2.show()
f.close()
seek() 

与load()方式类似,区别在于seek()方法用于定位到图像中的特定帧,特别是针对多帧图像(例如 GIF 动画)。

from PIL import Imagef = open('d:\\mask3\\2.gif', "rb")
im2 = Image.open(f)
im2.seek(2)
im2.show()
f.close()

同样的,seek()在使用中也要注意图像文件的生命周期。

下面的代码就会报错:

from PIL import Imagef = open('d:\\mask3\\2.gif', "rb")
im2 = Image.open(f)
im2.seek(2)
f.close()
im2.show()

 透明度混合alpha_composite()与blend()

alpha_composite()将两个半透明的图片叠加在一起,并根据 alpha 通道的数值进行合成,实现透明效果。 要确保两个图像的像素尺寸一致,并且它们都是 RGBA 模式的图像。

from PIL import Imageim1_path = 'd:\\mask3\\type_ARGB32_alpha1.png'
im2_path = 'd:\\mask3\\type_ARGB32_alpha2.png'
im1 = Image.open(im1_path)
im2 = Image.open(im2_path)im3 = Image.alpha_composite(im2, im1)
im3.show()

blend()方法是用于对两幅图像进行混合,根据给定的透明度参数对两幅图像进行加权混合。

from PIL import Imageim1_path = 'd:\\mask3\\type_ARGB32_alpha1.png'
im2_path = 'd:\\mask3\\type_ARGB32_alpha2.png'
im1 = Image.open(im1_path)
im2 = Image.open(im2_path)im3 = Image.blend(im1, im2, 0.2)
im3.show()

对于Image.blend(im1: Imageim2: Imagealpha: float)输出的图像:out = im1 * (1.0 - alpha) + im2 * alpha。

 

更新中。。。

这篇关于Python的Pillow(图像处理库)的一些学习笔记的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1042306

相关文章

python管理工具之conda安装部署及使用详解

《python管理工具之conda安装部署及使用详解》这篇文章详细介绍了如何安装和使用conda来管理Python环境,它涵盖了从安装部署、镜像源配置到具体的conda使用方法,包括创建、激活、安装包... 目录pytpshheraerUhon管理工具:conda部署+使用一、安装部署1、 下载2、 安装3

Python进阶之Excel基本操作介绍

《Python进阶之Excel基本操作介绍》在现实中,很多工作都需要与数据打交道,Excel作为常用的数据处理工具,一直备受人们的青睐,本文主要为大家介绍了一些Python中Excel的基本操作,希望... 目录概述写入使用 xlwt使用 XlsxWriter读取修改概述在现实中,很多工作都需要与数据打交

使用Python实现在Word中添加或删除超链接

《使用Python实现在Word中添加或删除超链接》在Word文档中,超链接是一种将文本或图像连接到其他文档、网页或同一文档中不同部分的功能,本文将为大家介绍一下Python如何实现在Word中添加或... 在Word文档中,超链接是一种将文本或图像连接到其他文档、网页或同一文档中不同部分的功能。通过添加超

Python MySQL如何通过Binlog获取变更记录恢复数据

《PythonMySQL如何通过Binlog获取变更记录恢复数据》本文介绍了如何使用Python和pymysqlreplication库通过MySQL的二进制日志(Binlog)获取数据库的变更记录... 目录python mysql通过Binlog获取变更记录恢复数据1.安装pymysqlreplicat

利用Python编写一个简单的聊天机器人

《利用Python编写一个简单的聊天机器人》这篇文章主要为大家详细介绍了如何利用Python编写一个简单的聊天机器人,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 使用 python 编写一个简单的聊天机器人可以从最基础的逻辑开始,然后逐步加入更复杂的功能。这里我们将先实现一个简单的

基于Python开发电脑定时关机工具

《基于Python开发电脑定时关机工具》这篇文章主要为大家详细介绍了如何基于Python开发一个电脑定时关机工具,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 简介2. 运行效果3. 相关源码1. 简介这个程序就像一个“忠实的管家”,帮你按时关掉电脑,而且全程不需要你多做

Python实现高效地读写大型文件

《Python实现高效地读写大型文件》Python如何读写的是大型文件,有没有什么方法来提高效率呢,这篇文章就来和大家聊聊如何在Python中高效地读写大型文件,需要的可以了解下... 目录一、逐行读取大型文件二、分块读取大型文件三、使用 mmap 模块进行内存映射文件操作(适用于大文件)四、使用 pand

python实现pdf转word和excel的示例代码

《python实现pdf转word和excel的示例代码》本文主要介绍了python实现pdf转word和excel的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价... 目录一、引言二、python编程1,PDF转Word2,PDF转Excel三、前端页面效果展示总结一

Python xmltodict实现简化XML数据处理

《Pythonxmltodict实现简化XML数据处理》Python社区为提供了xmltodict库,它专为简化XML与Python数据结构的转换而设计,本文主要来为大家介绍一下如何使用xmltod... 目录一、引言二、XMLtodict介绍设计理念适用场景三、功能参数与属性1、parse函数2、unpa

Python中使用defaultdict和Counter的方法

《Python中使用defaultdict和Counter的方法》本文深入探讨了Python中的两个强大工具——defaultdict和Counter,并详细介绍了它们的工作原理、应用场景以及在实际编... 目录引言defaultdict的深入应用什么是defaultdictdefaultdict的工作原理