python进阶之图像编程 pillow扩展库

一、概述

1.1pillow简介

Python Imaging Library (PIL)是python 下的图像处理模块,支持多种格式,并提供强大的图像处理功能,可以通过pip进行安装后使用。

1.2pillow具体应用

Pillow 库是 Python3 最常用的图像处理库,它支持多种图像格式,可以用于图像处理、图像增强、图像合成等。下面是 Pillow 库中的一些常用函数:open():打开一张图片;new():创建一张新的图片;save():保存一张图片;show():显示一张图片;resize():改变图片的大小;crop():裁剪图片;rotate():旋转图片;transpose():翻转图片;convert():转换图片的格式或色彩模式;filter():使用滤镜处理图片;getpixel():获取图片中指定位置的像素值;putpixel():设置图片中指定位置的像素值;paste():将一张图片粘贴到另一张图片上。

1.3快速入门

通过文件创建 Image 对象

通过文件创建 Image 图像对象是最常用的方法

示例:通过文件创建 Image 图像对象

from PIL import Imageimage = Image.open("D://桌面//1.jpeg")  # 创建图像实例
# 查看图像实例的属性
print(image.format, image.size, image.mode)image.show() # 显示图像

 格式转换并保存图像

pillow Image 模块中的 save 函数可以保存图片,除非你指定文件格式,否则文件的扩展名就是文件格式。

from PIL import Image
import os# 打开图片
image_path = "D://桌面//1.png"
image = Image.open(image_path)# 获取文件名与后缀
f, e = os.path.splitext(image_path)# 指定输出文件格式
output_format = "jpeg"  # 要保存的文件格式,比如 "PNG"、"JPEG" 等# 创建输出文件名
outfile = f + "." + output_format.lower()# 保存图片并指定文件格式
image.save(outfile, format=output_format)print(f"图片已保存为 {outfile},格式为 {output_format}")
image.show()

save() 函数有两个参数,如果文件名没有指定图片格式,那么第二个参数是必须的,他指定图片的格式。

二、课堂实操

2.1 创建缩略图

创建缩略图 使用 Image.thumbnail( size ), size 为缩略图宽长元组。

示例: 创建缩略图

from PIL import Image
import os# 打开图片
image_path = "D://桌面//1.png"
image = Image.open(image_path)# 获取文件名与后缀
f, e = os.path.splitext(image_path)# 指定输出文件格式
output_format = "PNG"  # 要保存的文件格式,比如 "PNG"、"JPEG" 等# 创建输出文件名
outfile = f + "_thumbnail." + output_format.lower()# 创建缩略图
thumbnail_size = (100, 100)  # 缩略图尺寸
image.thumbnail(thumbnail_size)# 保存缩略图并指定文件格式
image.save(outfile, format=output_format)print(f"缩略图已保存为 {outfile},格式为 {output_format}")

2.2剪贴,粘贴、合并图像

2.2.1Image类包含允许您操作图像中的区域的方法。如:要从图像中复制子矩形图像使用 crop() 方法。

2.2.2注意:将子图(region) 粘贴(paste)回原图时,粘贴位置 box 的像素与宽高必须吻合。而原图和子图的 mode 不需要匹配,Pillow会自动处理。

粘贴其它图片

from PIL import Image
import os# 打开图片
image_path = "D://桌面//1.jpeg"
image = Image.open(image_path)# 获取文件名与后缀
f, e = os.path.splitext(image_path)# 剪切区域
crop_box = (100, 100, 300, 300)  # 左上角坐标为 (100, 100),右下角坐标为 (300, 300)
cropped_image = image.crop(crop_box)# 打开另一张图片作为粘贴对象
paste_image_path = "D://桌面//2.jpeg"
paste_image = Image.open(paste_image_path)# 调整粘贴对象的尺寸和模式以匹配剪切区域
paste_image = paste_image.resize((crop_box[2] - crop_box[0], crop_box[3] - crop_box[1]))# 在原图上粘贴剪切区域
image.paste(paste_image, crop_box)# 保存合并后的图像
merged_outfile = f + "_merged." + e
image.save(merged_outfile)print(f"合并后的图像已保存为 {merged_outfile}")

当你从一个图像中剪切出一个区域,然后希望将这个剪切出的区域粘贴到另一个图像上时,剪切出的区域和粘贴目标的尺寸和模式(也就是图像的大小和颜色通道等信息)需要匹配,以确保粘贴操作能够成功。

在你的代码中,你已经定义了一个剪切区域 crop_box,这个区域的左上角坐标为 (100, 100),右下角坐标为 (300, 300)。剪切区域的宽度是 300 - 100 = 200,高度是 300 - 100 = 200。

粘贴自身图片

from PIL import Image
import os# 打开图片
image_path = "D://桌面//1.jpeg"
image = Image.open(image_path)# 获取文件名与后缀
f, e = os.path.splitext(image_path)# 剪切区域
crop_box = (100, 100, 300, 300)  # 左上角坐标为 (100, 100),右下角坐标为 (300, 300)
cropped_image = image.crop(crop_box)# 在原图上粘贴剪切区域
image.paste(cropped_image, crop_box)# 对粘贴的图像进行颠倒180度
region = image.crop(crop_box)
region = region.transpose(Image.ROTATE_180)# 将颠倒后的图像再次粘贴回原图上
image.paste(region, crop_box)# 保存合并后的图像
merged_outfile = f + "_merged1." + e
image.save(merged_outfile)print(f"合并后的图像已保存为 {merged_outfile}")

2.3几何变换

当使用Pillow(PIL)库的Image模块进行几何变换时,你可以使用rotate()方法或transpose()方法来实现不同类型的旋转和翻转。

使用rotate()方法进行图像旋转:

from PIL import Image# 打开图片
image_path = "D://桌面//1.jpeg"
image = Image.open(image_path)# 获取文件名与后缀
f, e = os.path.splitext(image_path)# 定义旋转角度(以度为单位,逆时针方向为正)
angle = 45# 旋转图像
rotated_image = image.rotate(angle)# 保存旋转后的图像
rotated_outfile = f + "_rotated." + e
rotated_image.save(rotated_outfile)print(f"旋转后的图像已保存为 {rotated_outfile}")

使用transpose()方法进行图像翻转:

from PIL import Image# 打开图片
image_path = "D://桌面//1.jpeg"
image = Image.open(image_path)# 获取文件名与后缀
f, e = os.path.splitext(image_path)# 对图像进行水平翻转
flipped_image_horizontal = image.transpose(Image.FLIP_LEFT_RIGHT)# 对图像进行垂直翻转
flipped_image_vertical = image.transpose(Image.FLIP_TOP_BOTTOM)# 保存翻转后的图像
flipped_horizontal_outfile = f + "_flipped_horizontal." + e
flipped_image_horizontal.save(flipped_horizontal_outfile)flipped_vertical_outfile = f + "_flipped_vertical." + e
flipped_image_vertical.save(flipped_vertical_outfile)print(f"水平翻转后的图像已保存为 {flipped_horizontal_outfile}")
print(f"垂直翻转后的图像已保存为 {flipped_vertical_outfile}")
out = im.transpose(Image.FLIP_LEFT_RIGHT) # 水平左右翻转
out = im.transpose(Image.FLIP_TOP_BOTTOM) # 垂直上下翻转
out = im.transpose(Image.ROTATE_90) # 逆时针90度
out = im.transpose(Image.ROTATE_180) # 逆时针180度
out = im.transpose(Image.ROTATE_270) # 逆时针270度

 2.4颜色变换

from PIL import Image
import numpy as np# 打开图片
image_path = "D://桌面//1.jpeg"
image = Image.open(image_path)# 获取文件名与后缀
f, e = os.path.splitext(image_path)# 改变图像亮度
brightness_factor = 1.5
brightened_image = Image.eval(image, lambda x: min(255, x * brightness_factor))# 修改图像通道颜色
r, g, b = image.split()
new_image = Image.merge("RGB", (b, r, g))# 保存修改后的图像
brightened_outfile = f + "_brightened." + e
new_image.save(brightened_outfile)print(f"修改后的图像已保存为 {brightened_outfile}")

Image.eval() 方法允许我们在像素级别对图像进行操作。在这个示例中,我们使用了一个lambda函数,将每个像素的值乘以亮度因子来改变图像的亮度。

使用 split() 和 merge() 方法来重新排列图像的颜色通道。在这个示例中,我们将原始图像的红色和蓝色通道进行交换,以改变颜色分布。

灰度图像

from PIL import Image# 打开图片
image_path = "D://桌面//1.jpeg"
image = Image.open(image_path)# 获取文件名与后缀
f, e = os.path.splitext(image_path)# 将彩色图像转换为灰度图像
gray_image = image.convert("L")# 保存灰度图像
gray_outfile = f + "_gray." + e
gray_image.save(gray_outfile)print(f"灰度图像已保存为 {gray_outfile}")

Pillow(PIL)库支持多种图像模式,每种模式具有不同的颜色通道和像素表示方式。以下是一些常见的图像模式:

  1. RGB("RGB"):每个像素由红色、绿色和蓝色通道组成,是彩色图像的常见模式。
  2. 灰度("L"):每个像素只有一个通道,表示像素的亮度值,用于灰度图像。
  3. RGBA("RGBA"):类似于RGB,还包括一个透明度通道,用于带有透明背景的彩色图像。
  4. CMYK("CMYK"):一种印刷颜色模式,使用青色、洋红色、黄色和黑色通道表示颜色。
  5. HSV("HSV"):使用色相、饱和度和值通道来表示颜色。
  6. 二值化("1"):每个像素只有一个二进制值,用于表示黑白图像。


可以根据需要使用convert()方法将图像从一种模式转换为另一种模式

2.5图像增强 

from PIL import Image, ImageEnhance# 打开图片
image_path = "D://桌面//1.jpeg"
image = Image.open(image_path)# 获取文件名与后缀
f, e = os.path.splitext(image_path)# 增强图像亮度
enhancer = ImageEnhance.Brightness(image)
brightened_image = enhancer.enhance(1.5)  # 1.5表示增强的倍数# 增强图像对比度
enhancer = ImageEnhance.Contrast(image)
high_contrast_image = enhancer.enhance(1.5)  # 1.5表示增强的倍数# 增强图像色彩
enhancer = ImageEnhance.Color(image)
colorful_image = enhancer.enhance(1.5)  # 1.5表示增强的倍数# 增强图像锐度
enhancer = ImageEnhance.Sharpness(image)
sharp_image = enhancer.enhance(2.0)  # 2.0表示增强的倍数# 保存增强后的图像
brightened_outfile = f + "_brightened." + e
high_contrast_outfile = f + "_high_contrast." + e
colorful_outfile = f + "_colorful." + e
sharp_outfile = f + "_sharp." + ebrightened_image.save(brightened_outfile)
high_contrast_image.save(high_contrast_outfile)
colorful_image.save(colorful_outfile)
sharp_image.save(sharp_outfile)print(f"亮度增强后的图像已保存为 {brightened_outfile}")
print(f"对比度增强后的图像已保存为 {high_contrast_outfile}")
print(f"色彩增强后的图像已保存为 {colorful_outfile}")
print(f"锐度增强后的图像已保存为 {sharp_outfile}")

其他图像增强功能可以使用 ImageEnhance 模块中的类。从图像创建后,可以使用 ImageEnhance 快速调整图片的对比度、亮度、饱和度和清晰度。

ImageEnhance 方法类型:

ImageEnhance.Contrast(im) 对比度
ImageEnhance.Color(im) 色彩饱和度
ImageEnhance.Brightness(im) 亮度
ImageEnhance.Sharpness(im) 清晰度

 处理单独通道

处理图像的单独通道意味着你可以选择性地对图像的红色、绿色、蓝色或灰度通道进行操作。Pillow(PIL)库允许你通过拆分图像的通道,对每个通道进行处理,然后重新合并通道来生成处理后的图像。

from PIL import Image# 打开图片
image_path = "D://桌面//1.jpeg"
image = Image.open(image_path)# 获取文件名与后缀
f, e = os.path.splitext(image_path)# 拆分图像的通道
r, g, b = image.split()# 处理单独的通道
r = r.point(lambda p: p * 0.8)  # 处理红色通道,降低亮度
g = g.point(lambda p: p * 1.2)  # 处理绿色通道,增加亮度
b = b.point(lambda p: p * 0.9)  # 处理蓝色通道,降低亮度# 合并通道
processed_image = Image.merge("RGB", (r, g, b))# 保存处理后的图像
processed_outfile = f + "_processed." + e
processed_image.save(processed_outfile)print(f"处理后的图像已保存为 {processed_outfile}")

处理灰度通道

from PIL import Image# 打开图片
image_path = "D://桌面//1.jpeg"
image = Image.open(image_path)# 获取文件名与后缀
f, e = os.path.splitext(image_path)# 将图像转换为灰度模式
gray_image = image.convert("L")# 处理灰度图像的单独通道
processed_gray_image = gray_image.point(lambda p: p * 0.8)  # 降低亮度# 保存处理后的灰度图像
processed_gray_outfile = f + "_processed_gray." + e
processed_gray_image.save(processed_gray_outfile)print(f"处理后的灰度图像已保存为 {processed_gray_outfile}")

2.6动态图像

Pillow 支持一些动态图像处理(如FLI/FLC,GIF等格式)。TIFF文件同样可以包含数帧图像。

打开动态图像时,PIL 会自动加载序列中的第一帧。你可以使用 seek 和 tell 方法在不同的帧之间移动。

2.7水印

Pillow(PIL)库允许你在图像上添加图像、文字或水印。

图像水印

from PIL import Image# 打开主图像和水印图像
main_image_path = "D://桌面//1.jpeg"
watermark_image_path = "D://桌面//2.jpeg"main_image = Image.open(main_image_path)
watermark_image = Image.open(watermark_image_path)# 将水印图像缩放到合适的大小
watermark_size = (100, 100)  # 替换为合适的尺寸
watermark_image = watermark_image.resize(watermark_size, Image.ANTIALIAS)# 创建一个透明度通道
alpha_channel = Image.new("L", watermark_image.size, 128)  # 128表示透明度(0为完全透明,255为不透明)# 将透明度通道与水印图像合并
watermark_image.putalpha(alpha_channel)# 计算水印位置(右下角)
main_width, main_height = main_image.size
watermark_width, watermark_height = watermark_image.size
x = main_width - watermark_width
y = main_height - watermark_height# 在主图像上添加透明水印
main_image.paste(watermark_image, (x, y), watermark_image)# 保存带有透明水印的图像
watermarked_outfile = f + "_watermarked." + e
main_image.save(watermarked_outfile)print(f"带有透明水印的图像已保存为 {watermarked_outfile}")

文本水印

from PIL import Image, ImageDraw, ImageFont# 打开图片
main_image_path = "D://桌面//1.jpeg"
main_image = Image.open(main_image_path)# 获取文件名与后缀
f, e = os.path.splitext(main_image_path)# 创建一个ImageDraw对象
draw = ImageDraw.Draw(main_image)# 定义水印文本和字体
watermark_text = "Watermark"
font = ImageFont.truetype("arial.ttf", 36)  # 替换为合适的字体路径和大小# 计算水印文本的尺寸
text_width, text_height = draw.textsize(watermark_text, font)# 创建一个透明度通道
alpha_channel = Image.new("L", (text_width, text_height), 128)  # 128表示透明度(0为完全透明,255为不透明)# 创建一个带有透明度的文本图像
watermark_text_image = Image.new("RGBA", (text_width, text_height))
watermark_draw = ImageDraw.Draw(watermark_text_image)
watermark_draw.text((0, 0), watermark_text, fill=(255, 255, 255, 128), font=font)  # 填充颜色和透明度# 计算水印位置(居中)
main_width, main_height = main_image.size
x = (main_width - text_width) // 2
y = (main_height - text_height) // 2# 在主图像上添加文本透明水印
main_image.paste(watermark_text_image, (x, y), watermark_text_image)# 保存带有文本透明水印的图像
watermarked_outfile = f + "_watermarked." + e
main_image.save(watermarked_outfile)print(f"带有文本透明水印的图像已保存为 {watermarked_outfile}")

2.8生成验证码图片

import random
from PIL import Image, ImageDraw, ImageFont# 创建验证码图像
width, height = 200, 100
background_color = (255, 255, 255)  # 白色背景
image = Image.new("RGB", (width, height), background_color)# 创建一个ImageDraw对象
draw = ImageDraw.Draw(image)# 创建一个字体对象
font = ImageFont.truetype("arial.ttf", 48)  # 替换为合适的字体路径和大小# 随机生成4个字符作为验证码
characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
code = "".join(random.choice(characters) for _ in range(4))# 计算每个字符的位置(居中)
text_width, text_height = draw.textsize(code, font)
x = (width - text_width) // 2
y = (height - text_height) // 2# 在图像上绘制验证码
draw.text((x, y), code, fill=(0, 0, 0), font=font)  # 使用黑色填充# 添加干扰线
for _ in range(5):x1 = random.randint(0, width)y1 = random.randint(0, height)x2 = random.randint(0, width)y2 = random.randint(0, height)draw.line((x1, y1, x2, y2), fill=(0, 0, 0), width=2)# 保存验证码图片
captcha_outfile = "captcha.png"
image.save(captcha_outfile)print(f"验证码图片已保存为 {captcha_outfile},验证码为: {code}")

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

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

相关文章

npm script命令

1 串行/并行执行命令 //串行 npm-run-all text test npm run text && npm run test //并行改成& npm-run-all --parallel text test npm run text & npm run test2 传递参数 {"lint": "eslint js/*.js","lint:fix"&#xff1a…

VBA Excel自定义函数的使用 简单的语法

一个简单的教程,实现VBA自定义函数。 新建模块 复制后面的代码放进来 函数的入口参数不定义,则认为是一块区域; 反之,如FindChar1 As String,则认为是输入的单值。 循环和分支如下例子,VB比较接近自然语…

第9章 【C语言】用户自己建立数据类型

9.1 定义和使用结构体变量 9.1.1 自己建立结构体类型 变量大多数是互相独立的、无内在联系的。C语言允许用户建立由不同类型数据组成的组合型的数据结构,它称为结构体。 在程序中可以自己建立一个结构体类型: struct Student{int num; //学号为整…

IDEA 配置注释模板

目录 一、配置类模板注释 二、配置方法注释 一、配置类模板注释 打开IDEA,打开settings(快捷键:Ctrl Alt s),选择Editor,找到File and Code Templates,设置需要配置注释的文件类型,如下图所示&#xf…

Git版本管理(04) git中常见问题整理

1 git pull 和git fetch之间的差别 git pull和git fetch都是用于从远程仓库获取更新的Git命令,它们之间的主要差别如下: git fetch:git fetch命令将从远程仓库下载最新的提交和分支信息,但不会自动合并或更新本地分支。执行git …

rust学习-引用C库

link和extern #[link(name = "...")] 是一个用于链接外部库的属性宏。 可以在 Rust 代码中引入其他语言编写的动态链接库(.so、.dll 等文件),从而实现 Rust 和其他语言的互操作。 #[link(name = "...")] 属性宏用于在 Rust 模块中引入标准 C 库(如 m…

入门超值型32位单片机MM32G0001开发板

灵动微入门级超值型MM32G0001系列MCU。采用48MHz ArmCortex-M0内核,提供16KB Flash和2KB SRAM,并提供丰富的外设资源。适用于多种多样的入门级32位MCU市场,可覆盖广泛的8/16位MCU升级需求。MM32G0001在各种温度范围内的闪存擦写寿命与数据保存…

服务器自动备份、打包、传输脚本

备份脚本 #!/bin/bash #author cheng #备份服务器自动打包归档每天的备份文件 Path/backhistory Host$(hostname) Date$(date %F) Dest${Host}_${Date}#创建目录 mkdir -p ${Path}/${Dest}#打包文件到目录 cd / && \#结合autoback.sh脚本,它往那个地方备&a…

MySQL执行更新的流程

一、加载缓存数据 引擎要执行更新语句的时候 ,比如对“id10”这一行数据,他其实会先将“id10”这一行数据看看是否在缓冲池里,如果不在的话,那么会直接从磁盘里加载到缓冲池里来,而且接着还会对这行记录加独占锁。 二…

MySQL数据库初体验

目录 一、数据库的基本概念 二、主流的数据库介绍 三、关系数据库与非关系数据库 1.关系数据库 一、数据库的基本概念 数据:描述事物的符号记录,包括数字、文字、图形、声音、档案记录等。以“记录的”形式按统一的格式进行存储 表:行(…

springboot中关于继承WebMvcConfigurationSupport后自定义的全局Jackson失效解决方法,localdate返回数组问题

一般情况下我们在config里增加jackson的全局配置文件就能满足基本的序列化需求,比如前后端传参的问题。 Configuration public class JacksonConfig {public static final String LOCAL_TIME_PATTERN "HH:mm:ss";public static final String LOCAL_DATE…

js判断类型:typeof Object.prototype.toString instanceof constructor有什么区别?一文讲清楚

相信很多小伙伴在使用js的过程中,经常会需要对js的数据类型进行判断,而js中可以对数据类型进行判断的方法有很多种,最常见的有typeof、Object.prototype.toString、instanceof、constructor这四种,那么他们有什么区别呢&#xff1…

软件测试之可靠性测试

CNAS标识 软件可靠性测试主要目的是通过在有使用代表性的环境中执行软件,以证实软件需求是否正确实现,为进行软件可靠性估计采集准确的数据,并找出所有对软件可靠性影响较大的错误。可靠性测试的特点是不同于硬件可靠性测试,主要…

最新Nmap入门技术

点击星标,即时接收最新推文 本文选自《web安全攻防渗透测试实战指南(第2版)》 点击图片五折购书 Nmap详解 Nmap(Network Mapper,网络映射器)是一款开放源代码的网络探测和安全审核工具。它被设计用来快速扫…

KUKA机器人零点标定的具体方法

KUKA机器人零点标定的具体方法 在进行机器人校正时,先将各轴置于一个定义好的机械位置,即所谓的机械零点。这个机械零点位置表明了同轴的驱动角度之间的对应关系,它用一个测量刻槽表示。 为了精确地确定机器人某根轴的机械零点位置,一般应先找到其预校正位置,然后去掉测量…

64位ATT汇编语言调用自己编写的两个数相加函数,使用printf输出,发现报错Segmentation fault

cat /etc/redhat-release看到操作系统是CentOS Linux release 7.6.1810,uname -r看到内核版本是3.10.0-957.el7.x86_64,gcc --version可以看到gcc版本是12.2.0,gdb --version可以看到gdb版本是12.1。 twoNumberPlus.s里边的内容如下&#x…

芯科科技宣布推出下一代暨第三代无线开发平台,打造更智能、更高效的物联网

第三代平台中的人工智能/机器学习引擎可将性能提升100倍以上 Simplicity Studio 6软件开发工具包通过新的开发环境将开发人员带向第三代平台 中国,北京 - 2023年8月22日 – 致力于以安全、智能无线连接技术,建立更互联世界的全球领导厂商Silicon Labs&…

【Unity 工程化】unity一些资源路径用途

Resources Resources 目录用于存放可以通过 Unity 的 Resources.Load 函数进行加载的资源。这些资源会在构建时被打包为一个单独的资源包,因此它们必须满足一些 Unity 所要求的命名和文件夹结构规则。由于这些资源被打包在一起,因此在构建后的游戏中可以…

提速换挡 | 至真科技用技术打破业务壁垒,助力出海破局增长

各个行业都在谈出海,但真正成功的又有多少? 李宁出海十年海外业务收入占比仅有1.3%,走出去战略基本失败。 京东出海业务磕磕绊绊,九年过去国际化业务至今在财报上都不配拥有姓名。 几百万砸出去买量,一点水花都没有…

小研究 - JVM 逃逸技术与 JRE 漏洞挖掘研究(一)

Java语言是最为流行的面向对象编程语言之一, Java运行时环境(JRE)拥有着非常大的用户群,其安全问题十分重要。近年来,由JRE漏洞引发的JVM逃逸攻击事件不断增多,对个人计算机安全造成了极大的威胁。研究JRE安…