python使用pil进行图像处理(等比例压缩、裁剪)实例代码


Posted in Python onDecember 11, 2017

PIL中设计的几个基本概念

1.通道(bands):即使图像的波段数,RGB图像,灰度图像

以RGB图像为例:

>>>from PIL import Image
>>>im = Image.open('*.jpg')   # 打开一张RGB图像
>>>im_bands = im.g
etbands() # 获取RGB三个波段
>>>len(im_bands)
>>>print im_bands[0,1,2]     # 输出RGB三个值

2.模式(mode):定义了图像的类型和像素的位宽。共计9种模式:

>>> im.mode
① 1:1位像素,表示黑和白,但是存储的时候每个像素存储为8bit。
② L:8位像素,表示黑和白。
③ P:8位像素,使用调色板映射到其他模式。
④ RGB:3x8位像素,为真彩色。
⑤ RGBA:4x8位像素,有透明通道的真彩色。
⑥ CMYK:4x8位像素,颜色分离。
⑦ YCbCr:3x8位像素,彩色视频格式。
⑧ I:32位整型像素。
⑨ F:32位浮点型像素。

3.尺寸(size):获取图像水平和垂直方向上的像素数

>>> im.size()

4.坐标系统(coordinate system):

PIL使用笛卡尔像素坐标系统,坐标(0,0)位于左上角。

注意:坐标值表示像素的角;位于坐标(0,0)处的像素的中心实际上位于(0.5,0.5)。

5.调色板(palette):

调色板模式("P")适用一个颜色调色板为每一个像素定义具体的颜色值。

6.信息(info)

>>> im.info() # 返回值为字典对象

7.滤波器(filters):将多个输入像素映射为一个输出像素的几何操作

PIL提供了4种不同的采样滤波器:

① NEAREST:最近滤波。从输入图像中选取最近的像素作为输出像素。

② BILINEAR:双线性内插滤波。在输入图像的2*2矩阵上进行线性插值。

③ BICUBIC:双立方滤波。在输入图像的4*4矩阵上进行立方插值。

④ ANTIALIAS:平滑滤波。对所有可以影响输出像素的输入像素进行高质量的重采样滤波,以计算输出像素值。

im.resize()和im.thumbnail()用到了滤波器

方法一:resize(size,filter = None)

>>> from PIL import Image 
>>> im = Image.open('*.jpg')
>>> im.size
>>> im_resize = im.resize((256,256)) #default 情况下是NEAREST插值方法
>>> im_resize0 = im.resize((256,256), Image.BILINEAR)
>>> im_resize0.size
>>> im_resize1 = im.resize((256,256), Image.BICUBIC)
>>> im_resize2 = im.resize((256,256), Image.ANTIALIAS)

方法二:im.thumbnail(size,filter = None)

对于pil的相关介绍就到这里了,下面分享一个使用pil进行图像处理(等比例压缩、裁剪)实例代码,如下:

#coding:utf-8
'''
  python图片处理
  @author:fc_lamp
  @blog:http://fc-lamp.blog.163.com/
'''
import Image as image
#等比例压缩图片
def resizeImg(**args):
  args_key = {'ori_img':'','dst_img':'','dst_w':'','dst_h':'','save_q':75}
  arg = {}
  for key in args_key:
    if key in args:
      arg[key] = args[key]
  im = image.open(arg['ori_img'])
  ori_w,ori_h = im.size
  widthRatio = heightRatio = None
  ratio = 1
  if (ori_w and ori_w > arg['dst_w']) or (ori_h and ori_h > arg['dst_h']):
    if arg['dst_w'] and ori_w > arg['dst_w']:
      widthRatio = float(arg['dst_w']) / ori_w #正确获取小数的方式
    if arg['dst_h'] and ori_h > arg['dst_h']:
      heightRatio = float(arg['dst_h']) / ori_h
    if widthRatio and heightRatio:
      if widthRatio < heightRatio:
        ratio = widthRatio
      else:
        ratio = heightRatio
    if widthRatio and not heightRatio:
      ratio = widthRatio
    if heightRatio and not widthRatio:
      ratio = heightRatio
    newWidth = int(ori_w * ratio)
    newHeight = int(ori_h * ratio)
  else:
    newWidth = ori_w
    newHeight = ori_h
  im.resize((newWidth,newHeight),image.ANTIALIAS).save(arg['dst_img'],quality=arg['save_q'])
  '''
  image.ANTIALIAS还有如下值:
  NEAREST: use nearest neighbour
  BILINEAR: linear interpolation in a 2x2 environment
  BICUBIC:cubic spline interpolation in a 4x4 environment
  ANTIALIAS:best down-sizing filter
  '''
#裁剪压缩图片
def clipResizeImg(**args):
  args_key = {'ori_img':'','dst_img':'','dst_w':'','dst_h':'','save_q':75}
  arg = {}
  for key in args_key:
    if key in args:
      arg[key] = args[key]
  im = image.open(arg['ori_img'])
  ori_w,ori_h = im.size
  dst_scale = float(arg['dst_h']) / arg['dst_w'] #目标高宽比
  ori_scale = float(ori_h) / ori_w #原高宽比
  if ori_scale >= dst_scale:
    #过高
    width = ori_w
    height = int(width*dst_scale)
    x = 0
    y = (ori_h - height) / 3
  else:
    #过宽
    height = ori_h
    width = int(height*dst_scale)
    x = (ori_w - width) / 2
    y = 0
  #裁剪
  box = (x,y,width+x,height+y)
  #这里的参数可以这么认为:从某图的(x,y)坐标开始截,截到(width+x,height+y)坐标
  #所包围的图像,crop方法与php中的imagecopy方法大为不一样
  newIm = im.crop(box)
  im = None
  #压缩
  ratio = float(arg['dst_w']) / width
  newWidth = int(width * ratio)
  newHeight = int(height * ratio)
  newIm.resize((newWidth,newHeight),image.ANTIALIAS).save(arg['dst_img'],quality=arg['save_q'])
#水印(这里仅为图片水印)
def waterMark(**args):
  args_key = {'ori_img':'','dst_img':'','mark_img':'','water_opt':''}
  arg = {}
  for key in args_key:
    if key in args:
      arg[key] = args[key]
  im = image.open(arg['ori_img'])
  ori_w,ori_h = im.size
  mark_im = image.open(arg['mark_img'])
  mark_w,mark_h = mark_im.size
  option ={'leftup':(0,0),'rightup':(ori_w-mark_w,0),'leftlow':(0,ori_h-mark_h),
       'rightlow':(ori_w-mark_w,ori_h-mark_h)
       }
  im.paste(mark_im,option[arg['water_opt']],mark_im.convert('RGBA'))
  im.save(arg['dst_img'])
#Demon
#源图片
ori_img = 'D:/tt.jpg'
#水印标
mark_img = 'D:/mark.png'
#水印位置(右下)
water_opt = 'rightlow'
#目标图片
dst_img = 'D:/python_2.jpg'
#目标图片大小
dst_w = 94
dst_h = 94
#保存的图片质量
save_q = 35
#裁剪压缩
clipResizeImg(ori_img=ori_img,dst_img=dst_img,dst_w=dst_w,dst_h=dst_h,save_q = save_q)
#等比例压缩
#resizeImg(ori_img=ori_img,dst_img=dst_img,dst_w=dst_w,dst_h=dst_h,save_q=save_q)
#水印
#waterMark(ori_img=ori_img,dst_img=dst_img,mark_img=mark_img,water_opt=water_opt)

总结

以上就是本文关于python使用pil进行图像处理(等比例压缩、裁剪)实例代码的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站:

如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!

Python 相关文章推荐
一篇不错的Python入门教程
Feb 08 Python
Python的包管理器pip更换软件源的方法详解
Jun 20 Python
python3使用PyMysql连接mysql数据库实例
Feb 07 Python
Python随机生成均匀分布在三角形内或者任意多边形内的点
Dec 14 Python
用十张图详解TensorFlow数据读取机制(附代码)
Feb 06 Python
Python实现登陆文件验证方法
Oct 06 Python
使用Python编写Prometheus监控的方法
Oct 15 Python
numpy向空的二维数组中添加元素的方法
Nov 01 Python
Python使用pydub库对mp3与wav格式进行互转的方法
Jan 10 Python
Python使用字典的嵌套功能详解
Feb 27 Python
python3.6使用tkinter实现弹跳小球游戏
May 09 Python
Django中在xadmin中集成DjangoUeditor过程详解
Jul 24 Python
让Python更加充分的使用Sqlite3
Dec 11 #Python
pandas中Timestamp类用法详解
Dec 11 #Python
Python排序搜索基本算法之插入排序实例分析
Dec 11 #Python
python实现二叉树的遍历
Dec 11 #Python
django上传图片并生成缩略图方法示例
Dec 11 #Python
使用Python的package机制如何简化utils包设计详解
Dec 11 #Python
python timestamp和datetime之间转换详解
Dec 11 #Python
You might like
让这部DC动画新作刷新你的认知
2020/03/03 欧美动漫
php格式化日期实例分析
2014/11/12 PHP
php实现微信公众平台发红包功能
2018/06/14 PHP
div+css布局的图片连续滚动js实现代码
2010/05/04 Javascript
jquery之empty()与remove()区别说明
2010/09/10 Javascript
基于jquery的固定表头和列头的代码
2012/05/03 Javascript
关于使用 jBox 对话框的提交不能弹出问题解决方法
2012/11/07 Javascript
JS完成代码前最好对其做5件事
2013/04/07 Javascript
JavaScript实现点击按钮后变灰避免多次重复提交
2013/07/15 Javascript
JS网页播放声音实现代码兼容各种浏览器
2013/09/22 Javascript
js控制不同的时间段显示不同的css样式的实例代码
2013/11/04 Javascript
Javascript学习笔记之 函数篇(二) : this 的工作机制
2014/06/24 Javascript
javascript中日期函数new Date()的浏览器兼容性问题
2015/09/05 Javascript
JS实现网站菜单拖拽移位效果的方法
2015/09/24 Javascript
BootStrap扔进Django里的方法详解
2016/05/13 Javascript
第十篇BootStrap轮播插件使用详解
2016/06/21 Javascript
ES6使用Set数据结构实现数组的交集、并集、差集功能示例
2017/10/31 Javascript
mui back 返回刷新页面的实例
2017/12/06 Javascript
jQuery中图片展示插件highslide.js的简单dom
2018/04/22 jQuery
Vue登录主页动态背景短视频制作
2019/09/21 Javascript
vue.js实现h5机器人聊天(测试版)
2020/07/16 Javascript
Python中元组,列表,字典的区别
2017/05/21 Python
Python随机生成均匀分布在单位圆内的点代码示例
2017/11/13 Python
python实现在IDLE中输入多行的方法
2018/04/19 Python
详解Python 函数如何重载?
2019/04/23 Python
Python Tkinter模块 GUI 可视化实例
2019/11/20 Python
python生成任意频率正弦波方式
2020/02/25 Python
CSS3实现王者荣耀匹配人员加载页面的方法
2019/04/16 HTML / CSS
AmazeUI图片轮播效果的示例代码
2020/08/20 HTML / CSS
Java面试题汇总
2015/12/06 面试题
介绍一下Ruby中的对象,属性和方法
2012/07/11 面试题
致共产党员倡议书
2014/04/16 职场文书
投资合作协议书
2014/04/17 职场文书
2015年中秋晚会主持词
2015/07/01 职场文书
学生会副主席竞选稿
2015/11/19 职场文书
高一语文教学反思
2016/02/16 职场文书