def img_chuli():
from PIL import ImageFilter,Image
from PIL import Image, ImageDraw, ImageFont,ImageEnhance,ImageChops,\
ImageFilter,TarIO,ImageSequence, PSDraw
import io
# 1、格式与读取
# '图像的格式:im:.格式format;大小size;宽度width;高度height;坐标元组:某像素点颜色值:getpixel(100, 100)
path = './img/0.jpg'
# 1.1读取
img = Image.open(path) # 打开
# 1.2从文件中读取
with open("0.ppm", "rb") as fp:
im = Image.open(fp)
#1.3从二进制流中读取
# im = Image.open(io.StringIO(buffer))
# 从tar文件中读取
fp = TarIO.TarIO("img.tar", "img/lena.ppm")
im = Image.open(fp)
# 1.4转格式
img = img.convert('L') #转灰度#,默认 RGB真彩;L灰;CMYK 印刷;RGBA 透明度真彩;YCbCr 彩色视频;LAB L * a * b颜色空间;HSV 等。
# L = R * 299 / 1000 + G * 587 / 1000 + B * 114 / 1000
img_array = np.array(img) # 转数组 #;np.asarray(im)浅拷贝;np.array() 深拷贝
im = Image.fromarray(np.uinit8(img_array * 255)) # 转图像
import matplotlib.pyplot as plt # plt 用于显示图片
plt.imshow('lena_1', cmap='Greys_r')
# img1= img[:, :, 0]#获取通道
# 1.5保存
img.save('red.png') # 保存
img.show() # 显示
# 1.6改扩展名
image_path='python-img.png' # 位置
file, extend = os.path.splitext(image_path) # 获取文件名与扩展名
outfile = file + ".jpg"
if image_path != outfile:
try:
if extend=='RGBA':#RGBA那么会出现异常, JPG 不支持透明度 ,所以要么丢弃Alpha
Image.open(image_path).convert("RGB").save(outfile) #转换RGB 格式,丢弃Alpha
else:
Image.open(image_path).save(outfile) # 修改文件格式
except IOError:
print("cannot convert", image_path)
# 2、创建图像Image.new(mode, size, color)**实现
img = Image.new('RGB', (100, 100), 'red')
# 2.1根据二维数组创建灰度图像
arr = (np.eye(300) * 255) # 二维数组
im1 = Image.fromarray(arr) # 转换为图像
im1.show()
# 2.2图像转数组序列
data1 = img.getdata() # 图像转数组序列
obj1 = []
for dt in data1:
obj1.append([sum(dt) / 3]) # 灰度方法:RGB三分量均值
# 转60 * 60 二维数组
obj = np.array(obj1).reshape((60, 60))
im = Image.fromarray(obj1)
im.show()
# 2.3颜色改变
img_width, img_height = 50, 50
# 填充占位数据
img_bytes = bytearray([0x70, 0x70, 0x70]) * img_width * img_height
i = 0
# 设置颜色渐变
for y in range(img_height):
for x in range(img_width):
img_bytes[i] = int(255.0 * (x / img_width)) # R
img_bytes[i + 1] = int(255.0 * (y / img_height)) # G
img_bytes[i + 2] = 0 # B
i += 3
image = Image.frombytes('RGB', (img_width, img_height), bytes(img_bytes))
image.show()
# 3、图像混合
# 3.1透明度混合:blend(im1, im2, alpha) ** 方法
# im1:透明度设置为(1 - apha);im2:透明度设置为(apha);
# alpha:透明度0 - 1;为0显示im1;1显示im2(A*apha+B*(1-apha));GB格式
im1 = Image.open('pic.jpg').convert(mode='RGB')#打开1
im2 = Image.new('RGB', im1.size, 'red')#按照1大小创建2
Image.blend(im1, im2, 0.5).show()#(A*apha+B*(1-apha))
# 3.2遮罩混合 Image.composite(im1, im2, mask :复合材料
im1 = Image.open('pic1.jpg')#
img2 = Image.open('pic2.jpg').resize(im1.size)
# 3.2.1
r,g,b =img2.split()#打开--大小--色到分离
Image.composite(im1, im2, b).show()
# 透明遮罩混合头像,创建复合图像。
im1 = Image.open('logo.png') # logo
im2 = Image.new(im1.mode, im1.size, "#000000") # 黑色
im3 = Image.new(im1.mode, im1.size, "#FFFFFF") # 白色
im4 = Image.composite(im3, im2, im1) # 蒙版:im1,im3粘贴到im2上
im4.show()
# 2.2.1.2 blend 混合
im1 = Image.open('logo.png') # logo
im2 = Image.new(im1.mode, im1.size, "#000000")#依据1模式,大小生成
im3 = Image.blend(im1, im2, 0.3)
im3.show()
3.2.2#分层处理
source= img2.split() # 打开--大小--色到分离
R, G, B = 0, 1, 2
mask = source[R].point(lambda i: i < 100 and 255) # 选择红色小于100的区域
out = source[G].point(lambda i: i * 0.7)# 处理绿色
source[G].paste(out, None, mask)# 粘贴已处理的通道,红色通道仅限于<100
im = Image.merge(im.mode, source) # 合并图像
# 3.3 单像素值修改
Image.eval(im, lambda x: x * 2).show()
def func(x): return x + 2
Image.eval(im, func)
# 3.复制、缩略图4
im2 = im.copy()
im2.thumbnail((100, 100))#缩略图
# 3.4图像粘贴剪切
# paste(im, box, mask)#(图像,粘贴区域,none大小一致)
im_crop = im1.crop((200, 200, 400, 400))#剪切
# im2.paste(im_crop, (30, 30))#(30,30点对齐粘贴
Image.getbbox() #获取图像非0区域的box值。
# Image.getcolors(maxcolors=256)返回值为(count, pixel)的列表。(出现的次数,像素的值)
# Image.histogram(mask=None, extrema=None)获取以 mack 为蒙版的直方图
# 3.5旋转和格式转换
im1.rotate(90).show()#旋转45度
im1.transpose(Image.ROTATE_45).show()#转置(矩)阵--FILP_TOP_BOTTOM上下;FILP_LEFT_RIGHT左右;ROTATE_90翻转90、180;TRANSPOSE颠倒
# 3.6通道分离、合并
r1, g1, b1 = im1.split()
im2 = Image.merge('RGB', [r1, g1, b1])
# 3.6滤镜
img_02 = img.filter(ImageFilter.GaussianBlur(radius=10))
img_02= img.filter(ImageFilter.GaussianBlur)# 高斯模糊处理
img_02 = img.filter(ImageFilter.BLUR)#模糊
img_02 = img.filter(ImageFilter.CONTOUR)#轮廓
img_02 = img.filter(ImageFilter.DETAIL)#细节
img_02 = img.filter(ImageFilter.EDGE_ENHANCE)#边缘增强,EDGE_ENHANCE_MORE深度边缘增强
# ImageFilter.SHARPEN为锐化滤波, 补偿图像的轮廓, 增强图像的边缘及灰度跳变的部分, 使图像变得清晰。
img_02 = img.filter(ImageFilter.EMBOSS)#浮雕
img_02 = img.filter(ImageFilter.SMOOTH)#平滑
# ImageFilter.SMOOTH_MORE为深度平滑滤波, 会使得图像变得更加平滑。
img_02 = img.filter(ImageFilter.FIND_EDGES) #寻找边缘滤波
# 卷积滤波
im = im1.filter(ImageFilter.Kernel((3, 3), (1, 1, 1, 0, 0, 0, 2, 0, 2)))
im = im1.filter(ImageFilter.RankFilter(5, 20))#等级滤波:5x5--25个中,排序20的像素为新值
im = im1.filter(ImageFilter.MaxFilter(5))#最大滤波:5x5区域25点最大像素为新值
im = im1.filter(ImageFilter.ModeFilter(5))#模式滤波:5x5中次数最多像素新值
# 3.7 图像运算
ImageChops.add(im1, im2, scale=1.0, offset=0)
im2 = ImageChops.add(im1, im2) # 输出out = 1/scale*(im1 + im2) + offset
im2 = ImageChops.subtract(im1, im2) # out = (im1 - im2) / scale + offset
# 对图像进行各种操作
im3 = ImageChops.darker(im1, im2)#取对比像素较小者
im3 = ImageChops.lighter(im1, im2)#像素取大
im3 = ImageChops.invert(im1)#反色
im3 = ImageChops.multiply(im1, im2)#相乘
im3 = ImageChops.screen(im1, im2)#屏幕
im3 = ImageChops.difference(im1, im2)#差异
# 3.8ImageEnhance:增强(色彩、亮度)
# 获取颜色(各种)调整器
enhance_im1 = ImageEnhance.Color(im1)#颜色
enhance_im1 = ImageEnhance.Contrast(im1)#对比度
enhance_im1.enhance(1.5).show("增加50%对比度")
enhance_im1 = ImageEnhance.Brightness(im1)#亮度
enhance_im1 = ImageEnhance.Sharpness(im1)#清晰度
im2 = enhance_im1.enhance(0.1)#颜色减弱
im2 = enhance_im1.enhance(1.1)# 增强颜色
im1 = im1.point(lambda x: x * 0.3)#像素点操作
# 3.9绘制
im = Image.new("RGB", (200, 300), "white")#创建图片
drawer = ImageDraw.Draw(im)#绘制
drawer.line((0, 0, 150, 150), fill='green', width=2)#直线或曲线(起点、终点)、颜色、轮廓、连接
drawer.rectangle((5, 50, 150, 150), fill='green', outline='red', width=3)#矩形(起点、终点)、颜色、轮廓、连接
drawer.arc((5, 50, 150, 150), start=0, end=90, fill='green', width=3)#圆弧(起点、终点)、起始角度、终止角度、颜色、轮廓、连接
drawer.ellipse((5, 50, 150, 150), fill='green', outline='red', width=3)#椭圆(起点、终点)、起始角度、终止角度、颜色、轮廓色
drawer.chord((50, 50, 150, 150),start=0, end=90, fill='green', outline='red', width=3)#弦(起点、终点)、起始角度、终止角度、颜色、轮廓色
drawer.pieslice((5, 50, 150, 150),start=0, end=90, fill='green', outline='red', width=3) #扇形区--同上
drawer.polygon((5, 50, 150, 150, 150, 200, 200, 250, 50, 50), fill='green', outline='red')#多边形
drawer.point((10, 100), fill='black') #点
drawer.text((10, 100), text='hello' ,fill='red') #英文文字
imFont = ImageFont.truetype('simkai.ttf', 30)
drawer.text((50, 100), text="啥", font=imFont, fill="red")
# 4.0动态图
# 4.1
im = Image.open("animation_1.gif")
im.seek(2) # 跳到第3帧
try:
while 1:
im.seek(im.tell() + 1) # tell() 获取当前帧索引
except EOFError: # 读最后一帧,Pillow抛出EOFError异常。
pass # 结束
# 4.2
for frame in ImageSequence.Iterator(im):
im=frame
# 4.3保存
im.save(out, save_all=True, append_images=[im1, im2, ...]) #动态保存 GIF,PDF,TIFF和WebP
# 4.7 Postscript Printer:图添加图像或文字
# 4.7.0准备
im = Image.open("img1.jpg")
title = "mohe_wuting"
box = (2 * 72, 3 * 72, 9 * 72, 11 * 72) # in points
ps_1 = PSDraw.PSDraw() # 默认:sys.stdout
ps_1.begin_document(title)
#4.7.1 画出图像 (75 dpi)
ps_1.image(box, im, 75)
ps_1.rectangle(box)
#4.7.2 画出标题
ps_1.setfont("HelveticaNarrow-Bold", 36)
ps_1.text((3 * 72, 4 * 72), title)
# 4.7.3绘制文字
# ImageDraw.text(xy, text, fill=None, font=None, anchor=None, spacing=0, align="left", direction=None, features=None)
im = Image.new('RGB', (200, 200), 0)
draw = ImageDraw.Draw(im)# 创建可绘对象
font = ImageFont.truetype('arialbi.ttf', 32)# 设字体,字体库位于前目录
draw.text((8, 8), "anyang_wang", font=font, fill="#FFFFFF")# 填充文字
draw.multiline_text((10, 10), "anyang,\nwang", font=font, fill="#FFFFFF")
# ImageDraw.textsize(text, font=None, spacing=4, direction=None, features=None)#获取文字的大小
draw.textsize('anyang_wang', font)
draw.multiline_textsize('Hello,\nwoodman', font)#获取带换行的文字的大小
# 7.8:高速解码--加载器 draft
im.draft("L", (50, 50))
def pinjie():
import os
from PIL import Image
from random import sample, choices
COL = 10 # 拼接图片列数
ROW = 20 # 拼接图片行数
UNIT_HEIGHT_SIZE = 800 # 高度
UNIT_WIDTH_SIZE = 400 # 宽度
PATH = "" # 拼接图片路径
NAME = "mohe_wuting" # 拼接出的图片保存的名字
RANDOM_SELECT = False # 设置是否可重复抽取图片
SAVE_QUALITY = 60 # 保存的图片的质量 可选0-100
# 图片复制拼接
def concat_img(img_names, name, path):
image_files = []
for index in range(COL * ROW):
image_files.append(Image.open(path + image_names[index])) # 读取所有拼接图
target = Image.new('RGB', (UNIT_WIDTH_SIZE * COL, UNIT_HEIGHT_SIZE * ROW)) # 创建成图画布
# 参数1RGB;参数2:传入元组指定图片大小,参数3:可指定颜色,默认为黑色
for row in range(ROW):
for col in range(COL):
# 图片逐行拼接
# paste:参数1--指定需拼接图片,参数2:二元元组(指定复制位置左上角坐标)#或四元元组(指定复制位置的左上角和右下角坐标)
target.paste(image_files[COL * row + col], (0 + UNIT_WIDTH_SIZE * col, 0 + UNIT_HEIGHT_SIZE * row))
target.save(path + name + '.jpg', quality=SAVE_QUALITY) # 成品保存
# 获取需拼图名称
def get_image_names(path):
image_names = list(os.walk(path))[0][2] # 获取目标文件夹下所有文件文件名
# 1、用list将iterator转成list,2、再[0]取出里面的三元元组元素,再[2]取出元组中的由文件夹名组成的列表
# 从所有文件中随机抽取需要数量文件,可设置是否能重复抽取
# random库中的choices函数用于可放回抽取,第一个参数指定用于抽取的对象,k参数指定抽取数量
# sample函数用于不放回抽取,参数同上
selected_images = choices(image_names, k=COL * ROW) if RANDOM_SELECT else sample(image_names, COL * ROW)
return selected_images
if __name__ == '__main__':
concat_img(get_image_names(PATH), NAME, PATH)
python_图像_PIL_img
最新推荐文章于 2023-07-28 15:52:49 发布