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

news2024/11/15 11:33:11

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

安装Pillow库:

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

pip install pillow 

升级库:

pip install pillow --upgrade 

一些基础的应用 

1、图像文件方面的:

打开文件

1)直接打开文件:

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

from PIL import Image
import io

im1 = 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 io

with 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 io

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

im2.show()

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

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

import io

from PIL import Image

f = 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 Image


f = 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 Image

file_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 Image

file_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 Image

file_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 Image

file_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 Image

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

im2.show()

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

from PIL import Image

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

im2.show()

 需要改成:

from PIL import Image

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

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

from PIL import Image

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

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

下面的代码就会报错:

from PIL import Image

f = 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 Image

im1_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 Image

im1_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。

 

更新中。。。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1801135.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

植物大战僵尸杂交版破解C++实现

文章目录 前言准备工作:基地址与偏移UI界面设计和绑定项目模板总览图生成与实现信号处理1、阳光值更新:BTN12、三种钱币值更新:BTN2-BTN43、冷却刷新:BTN54、锁定阳光:check15、无冷却:check26、OnTimer()和OnClose&am…

数 据 类 型

概述 Java 是强类型语言。 每一种数据都定义了明确的数据类型,在内存中分配了不同大小的内存空间(字节)。 Java 中一共有 8 种基本类型(primitive type),包括 4 种整型、2 种浮点型、1 种字符类型&#…

【C语言】07.函数

一、概念 C语言的函数,有些翻译为:子程序,子程序这种翻译更加准确⼀些。 C语言中的函数就是⼀个完成某项特定的任务的⼀小段代码。这段代码是有特殊的写法和调用方法的。 C语言的程序其实是由无数个小的函数组合而成的,也可以说&…

什么是SIEM

SIEM 解决方案是一种企业级应用程序,可集中和自动化与网络安全相关的操作,该工具通过收集、分析和关联从组织 IT 基础设施中的各种实体聚合的网络事件来帮助应对网络威胁。 与帮助监控和评估组织物理空间中的危险的监视控制台相比,SIEM解决方…

【百万字详解Redis】主从复制

文章目录 一、主从复制概述1.1、单机问题1.1.1、机器宕机1.1.2、容器瓶颈1.1.3、QPS瓶颈 1.2、什么是主从复制1.3、主从复制形式1.3.1、一主一从1.3.2、一主多从 1.4、主从复制作用 二、单机主从2.1、复制redis.conf2.2、配置主机2.3、配置从机2.4、启动服务2.5、读写分离 三、…

[工具探索]富士mini90拍立得使用指南

文章目录 1. 基本功能介绍1.1 相机外观1.2 电池与胶片 2. 设置相机2.1 装入电池2.2 装入胶片 3. 拍摄模式3.1 标准模式3.2 儿童模式3.3 远景模式3.4 双重曝光模式3.5 Bulb(B)模式3.6 **派对模式**3.7 微距模式3.8 **亮度模式**3.9 **定时拍摄模式**3.10 …

php探针代码怎么写

创建php文件并输入代码,访问文件查看php版本、环境和系统配置信息,可使用ini_set()函数定制输出,但注意在生产环境中使用时要注重安全,因为它会泄露敏感信息。 PHP探针代码撰写指南 PHP探针代码是一种脚本,可提供关于…

基于Java Mq的数据交换平台实现_设计消息的格式和内容

基于Java Mq的数据交换平台实现 目录概述需求: 设计思路实现思路分析 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy,skip hardness,make a better result,wait for change,challen…

FileZilla:不安全的服务器,不支持 FTP over TLS 原因与解决方法

今天在用FileZilla Client连接某个主机的FTP的时候,主机地址、账号、密码、端口确定百分之百正确的情况下,结果报错如下: 状态: 正在解析 x.x.x 的地址 状态: 正在连接 x.x.x.x:21... 状态: 连接建立,等待欢迎消息... 状态: 不安全…

6.6SSH的运用

ssh远程管理 ssh是一种安全通道协议,用来实现字符界面的远程登录。远程复制,远程文本传输。 ssh对通信双方的数据进行了加密 用户名和密码登录 密钥对认证方式(可以实现免密登录) ssh 22 网络层 传输层 数据传输的过程中是加密的 …

Java Web学习笔记19——Ajax介绍

Ajax: 概念:Asynchronous JavaScript And XML 异步的JavaScript和XML。 作用: 1)数据交换:通过Ajax可以给服务器发送请求,并获得服务器的响应数据。 2)异步交互:可以在不重新加载页面的情况…

【NetTopologySuite类库】生成凸包

介绍 计算几何体的凸包。凸包是最小的凸几何体,包含输入几何体中的所有点。使用Graham Scan算法。 API地址: https://nettopologysuite.github.io/NetTopologySuite/api/NetTopologySuite.Algorithm.ConvexHull.html 示意图 示例代码 需在NuGet中安装…

nomachine使用记录以及录包

录包命令: rosbag record 话题名字(可以是原相机话题和执行程序的话题)rosbag play 包名(可以离线播放包的数据) rqt_image_view 话题可视化

新买的移动硬盘无法识别

文章目录 背景解决方案 背景 同事新买的移动硬盘,插在电脑上识别不出来盘符,检查了一下,硬盘没问题应该,是ssk的硬盘盒M.2的SSD,硬盘驱动也是正常的,插拔了几次,都不识别,换了太电脑…

未见过类型题每周总结(个人向)

1.DP40 小红取数 题目 解析 一道01背包的衍生问题,我们可以按照它的思路定义数组dp[i][j],表示前i个数中%k为j的最大和。为什么设置未%k的最大和呢?是因为当两个数分别%k,如a%kx,b%ky。那么(ab)%k&#…

FENDI CLUB精酿啤酒品鉴体验

当提及“品质卓越,口感非凡”的啤酒时,FENDI CLUB精酿啤酒无疑是一个值得一试的选择。这款啤酒以其独特的酿造工艺和优质的原料,为消费者带来了与众不同的味觉享受。 一、独特的酿造工艺 FENDI CLUB精酿啤酒在酿造过程中,严格遵循…

关于 spring boot 的 目录详解 和 配置文件 以及 日志

目录 配置文件 spring boot 的配置文件有两种格式,分别是 properties 和 yml(yaml)。这两种格式的配置文件是可以同时存在的,此时会以 properties 的文件为主,但一般都是使用同一种格式的。 格式 properties 语法格…

使用 Django 创建 App

文章目录 步骤 1:创建 Django 项目步骤 2:创建 App步骤 3:配置 App步骤 4:编写代码步骤 5:运行服务器 在 Django 中,App 是组织代码的基本单元,它可以包含模型、视图、模板等组件,帮…

Hadoop的Windows环境准备

一、将Hadoop传输到Windows中 1、备份副本 cp -r /opt/softs/hadoop3.1.3/ /opt/softs/hadoop3.1.3_temp 2、删除备份的share目录 cd /opt/softs/hadoop3.1.3_temp rm -rf share/ 3、下载到Windows中 重命名去掉_temp 4、删除备份文件 rm -rf /opt/softs/hadoop3.1.3_t…

Redis到底支不支持事务?

文章目录 一、概述二、使用1、正常执行:2、主动放弃事务3、全部回滚:4、部分支持事务:5、WATCH: 三、事务三阶段四、小结 redis是支持事务的,但是它与传统的关系型数据库中的事务是有所不同的 一、概述 概念: 可以一次执行多个命令,本质是一…