别再@官方啦,10行代码给自己头像加国旗
- 2019 年 10 月 8 日
- 笔记
最近打开朋友圈,全是@微信官网,求图像加国庆喜庆的图片。然而,我虔诚的等了很久却没等到。求人不如靠自己,自己动手解决。
在日常生活中,我们需要处理图片的地方有很多,像这次是加国旗,下次可能就是加个圣诞帽。不会PS怎么办,万能的python可以搞定一切。
python中图像处理的库有很多,这次就拿常见的两种来实现一下如何在自己公众号图片中加上国旗图案。顺便巩固一下这两个库的常见用法。
PIL/ Pillow
PIL (Python Imaging Library)是一个免费的Python编程语言库,它增加了对打开、处理和保存许多不同图像文件格式的支持。该库包含基本的图像处理功能,包括点操作、使用一组内置卷积内核进行过滤以及颜色空间转换。
安装很简单
pip install pillow
如下便是代码:
from PIL import Image im_path = r'/Users/anderson/Downloads/qrcode.jpg' im = Image.open(im_path) width, height = im.size #查看一下底图的大小 print(width,height) im_path2 = r'/Users/anderson/Downloads/flag3.jpg' im2 = Image.open(im_path2) im3 = im2.resize(width/4,height/4) #将要贴入的图压缩到底图的四分之一大小 width3, height3 = im3.size print(width3,height3) cropedIm = im.copy() #避免动了原图 copyIm = im3.copy() cropedIm.paste(copyIm, 3*width/4,3*height/4) #在四分之三出贴入 cropedIm.show() cropedIm.save(r'/Users/anderson/Downloads/result.jpg')
去掉那些打印给自己看的print,确实只有10行,效果如下:

下面来看看这个库常用的模块
Python Image模块基本图像处理
导入需要的图像库:
import Image
读取一张图片:
im=Image.open('/home/Picture/test.jpg')
显示一张图片:
im.show()
保存图片:
im.save(``"save.gif"``,``"GIF"``) #保存图像为gif格式
创建新图片:
Image.new(mode,size) Image.new(mode,size,color)
例子:
from PIL import Image im_path = r'pathtoopen.jpg' im = Image.open(im_path) width, height = im.size # 宽高 print(im.size, width, height) # 格式,以及格式的详细描述 print(im.format, im.format_description) im.save(r'pathtoresult.jpg') im.show()
im.size返回一个元组,分别是宽和高。show()方法会调用系统默认图像查看软件,打开并显示。im.format可查看图像的格式。save()可保存处理后的图片,如果未经处理,保存后的图像占用的空间(字节数)一般也与原图像不一样,可能经过了压缩。
Pillow也可以新建空白图像, 第一个参数是mode即颜色空间模式,第二个参数指定了图像的分辨率(宽x高),第三个参数是颜色。 可以直接填入常用颜色的名称。如'red' 也可以填入十六进制表示的颜色,如#FF0000表示红色。 还能传入元组,比如(255, 0, 0, 255)或者(255, 0, 0)表示红色。
# 通常使用RGB模式就可以了 newIm= Image.new('RGB', (100, 100), 'red') newIm.save(r'result1.png') # 也可以用RGBA模式,还有其他模式查文档吧 blcakIm = Image.new('RGB',(200, 100), 'red') blcakIm.save(r'result2.png') # 十六进制颜色 blcakIm = Image.new('RGBA',(200, 100), '#FF0000') blcakIm.save(r'result3.png') # 传入元组形式的RGBA值或者RGB值 # 在RGB模式下,第四个参数失效,默认255,在RGBA模式下,也可只传入前三个值,A值默认255 blcakIm = Image.new('RGB',(200, 100), (255, 255, 0, 120)) blcakIm.save(r'result4.png')
图片裁剪:
box=(100,100,500,500) #设置要裁剪的区域 region=im.crop(box) #此时,region是一个新的图像对象。
Image有个crop()方法接收一个矩形区域元组。返回一个新的Image对象,是裁剪后的图像,对原图没有影响。
两张图片相加:
Image.blend(img1,img2,alpha) # 这里alpha表示img1和img2的比例参数
Image.blend(image1,image2,alpha):通过使用常量alpha在给定图像之间进行差值来创建新图像,两个图像必须具有相同的大小和模式,aplha为0则返回第一张图像的拷贝,为1则返回第二张图像的拷贝,可以去中间值来划分偏差如0.5
拷贝图像: im.crop(box):从当前图像返回矩形区域的副本,box是一个4元祖,定义从左、上、右、下的像素坐标
#剪切图像 box=(100,100,400,400) #定义了图像的坐标位置,从左、上、右、下 im=Image.open('images/22.jpg','r') print(im.size) region=im.crop(box) #它会从左上角开始,同时向下和向右移动100像素的位置开始截取400-100的像素宽高,也就是300x300的图像 print(region.size) region.save('images/300x300.jpg')
图像黏贴(合并)
im.paste(region,box)#粘贴box大小的region到原先的图片对象中。
copy函数如其名会产生一个原图像的副本,在这个副本上的任何操作不会影响到原图像。paste()方法用于将一个图像粘贴(覆盖)在另一个图像上面。谁调用它,他就在该Image对象上直接作修改。 所以paste前最好使用copy()复制一个副本,在此副本操作,不会影响到原图信息。虽然在程序里原图信息已改变,但由于保存文件时用的其他文件名,相当于改变没有生效,所以查看的时候原图还是没有改变的。
im = Image.open(im_path) cropedIm = im.crop((700, 100, 1200, 1000)) copyIm = im.copy() copyIm.paste(cropedIm, (0, 0)) im.show() copyIm.save(r'paste.png')
调整图像的大小 resize方法返回指定宽高度的新Image对象,接受一个含有宽高的元组作为参数。宽高的值得是整数。
im = Image.open(im_path) width, height = im.size resizedIm = im.resize((width, height+(1920-1080))) resizedIm.save(r'resize.png')
旋转和翻转图像 rotate()返回旋转后的新Image对象, 保持原图像不变。逆时针旋转。
out=img.rotate(45) #逆时针旋转45度
Python-OpenCV基本操作cv2
OpenCV( 开源计算机视觉库,Open Source Computer Vision Library)是计算机视觉应用中使用最广泛的库之一。OpenCV-Python是OpenCV的python API。OpenCV-Python不仅速度快(因为后台由用C / C ++编写的代码组成),也易于编码和部署。这使其成为执行计算密集型计算机视觉程序的绝佳选择。 安装也很简单:
pip install cv2
错,这是一般网上教你的方法,实际你可能要用到
pip install opencv-python
图片加载、显示和保存
import cv2 # 生成图片 img = cv2.imread("1.jpg") # 生成灰色图片 imgGrey = cv2.imread("1.jpg", 0) # 展示原图 cv2.imshow("img", img) # 展示灰色图片 cv2.imshow("imgGrey", imgGrey) # 等待图片的关闭 cv2.waitKey() # 保存灰色图片 cv2.imwrite("Copy.jpg", imgGrey)
图像显示窗口创建与销毁 cv2.namedWindow(窗口名,属性) 创建一个窗口
属性—指定窗口大小模式: cv2.WINDOW_AUTOSIZE:根据图像大小自动创建大小 cv2.WINDOW_NORMAL:窗口大小可调整 cv2.destoryAllWindows(窗口名) 删除任何建立的窗口
图片宽、高、通道数获取 img.shape 返回图像高(图像矩阵的行数)、宽(图像矩阵的列数)和通道数3个属性组成的元组,若图像是非彩色图,则只返回高和宽组成的元组
import cv2 img = cv2.imread("1.jpg") imgGrey = cv2.imread("1.jpg", 0) sp1 = img.shape sp2 = imgGrey.shape
图像像素数目和图像数据类型的获取 图像矩阵img的size属性和dtype分别对应图像的像素总数目和图像数据类型。一般情况下,图像的数据类型是uint8。
import cv2 img = cv2.imread("1.jpg") imgSize = img.size print(imgSize) ty = img.dtype print(ty)
生成指定大小的空图像
import cv2 import numpy as np img = cv2.imread("1.jpg") imgZero = np.zeros(img.shape, np.uint8) imgFix = np.zeros((300, 500, 3), np.uint8) cv2.imshow("img", img) cv2.imshow("imgZero", imgZero) cv2.imshow("imgFix", imgFix) cv2.waitKey()
图像三通道分离和合并 分离图像通道可以使用cv2中的split函数,合并使用merge函数。
import cv2 img = cv2.imread("01.jpg") b , g , r = cv2.split(img) merged = cv2.merge([b,g,r]) cv2.imshow("Blue",b) cv2.imshow("Green",g) cv2.imshow("Red",r) cv2.imshow("Merged",merged) cv2.waitKey()
在图像上输出文字 使用putText函数在图片上输出文字,函数原型: putText(img, text, org, fontFace, fontScale, color, thickness=None, lineType=None, bottomLeftOrigin=None)
img:图像 text:要输出的文本 org:文字的起点坐标 fontFace:字体 fontScale:字体大小 color:字体颜色 thickness:字图加粗
import cv2 img = cv2.imread("01.jpg") cv2.putText(img,"Print some text to img",(100,100),cv2.FONT_HERSHEY_SIMPLEX,1,(0,0,255)) cv2.imshow("img",img) cv2.waitKey()
图像缩放 缩放使用cv2.resize()函数,resize函数里的size第一个是宽(列),第二个是高(行)。
import cv2 img = cv2.imread("1.jpg") cv2.imshow("img", img) imgg = cv2.resize(img, (200, 100)) cv2.imshow("imgg", imgg) cv2.waitKey()
OK, 我们尝试一下用这个库生成图片:
import cv2 # 读取图片 img_head = cv2.imread('/Users/anderson/Downloads/qrcode.jpg') img_flag = cv2.imread('/Users/anderson/Downloads/flag2.jpg') # 获取宽度 w_head, h_head = img_head.shape[:2] w_flag, h_flag = img_flag.shape[:2] # 计算比例 scale = w_head / w_flag / 4 # 缩放图案 img_flag = cv2.resize(img_flag, fx=scale, fy=scale) # 获取缩放后新宽度 w_flag, h_flag = img_flag.shape[:2] # 按3个通道合并图片 for c in range(0, 3): img_head[w_head - w_flag:, h_head - h_flag:, c] = img_flag[:, :, c] # 保存结果 cv2.imwrite('/Users/anderson/Downloads/new_head.jpg', img_head)
效果如下:
