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中xrange和range的区别
May 13 Python
从零学python系列之从文件读取和保存数据
May 23 Python
Python使用redis pool的一种单例实现方式
Apr 16 Python
Python PyAutoGUI模块控制鼠标和键盘实现自动化任务详解
Sep 04 Python
python利用pandas将excel文件转换为txt文件的方法
Oct 23 Python
pycham查看程序执行的时间方法
Nov 29 Python
java判断三位数的实例讲解
Jun 10 Python
在Python中os.fork()产生子进程的例子
Aug 08 Python
Python sys模块常用方法解析
Feb 20 Python
django xadmin 管理器常用显示设置方式
Mar 11 Python
Python实现封装打包自己写的代码,被python import
Jul 12 Python
Python内置数据类型中的集合详解
Mar 18 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
PHP框架Laravel的小技巧两则
2015/02/10 PHP
PHP面向对象多态性实现方法简单示例
2017/09/27 PHP
javascript ajax 仿百度分页函数
2013/10/29 Javascript
avascript中的自执行匿名函数应用示例
2014/09/15 Javascript
通过Ajax使用FormData对象无刷新上传文件方法
2016/12/08 Javascript
Vue 2.0+Vue-router构建一个简单的单页应用(附源码)
2017/03/14 Javascript
canvas简单快速的实现知乎登录页背景效果
2017/05/08 Javascript
利用ES6的Promise.all实现至少请求多长时间的实例
2017/08/28 Javascript
Angular.js中window.onload(),$(document).ready()的写法浅析
2017/09/28 Javascript
Vue实现点击时间获取时间段查询功能
2020/08/21 Javascript
js中的 || 与 &amp;&amp; 运算符详解
2018/05/24 Javascript
35个最好用的Vue开源库(史上最全)
2019/01/03 Javascript
vue.js路由mode配置之去掉url上默认的#方法
2019/11/01 Javascript
Vue中keep-alive 实现后退不刷新并保持滚动位置
2020/03/17 Javascript
Vue实现一种简单的无限循环滚动动画的示例
2021/01/10 Vue.js
[04:14]从西雅图到上海——玩家自制DOTA2主题歌曲应援TI9
2019/07/11 DOTA
python采集博客中上传的QQ截图文件
2014/07/18 Python
python实现的文件夹清理程序分享
2014/11/22 Python
快速排序的算法思想及Python版快速排序的实现示例
2016/07/02 Python
python2.7和NLTK安装详细教程
2018/09/19 Python
Django结合ajax进行页面实时更新的例子
2019/08/12 Python
python安装本地whl的实例步骤
2019/10/12 Python
python实现企业微信定时发送文本消息的示例代码
2020/11/24 Python
爱游人:Travelliker
2017/09/05 全球购物
全球速卖通西班牙站:AliExpress西班牙
2017/10/30 全球购物
澳大利亚领先的运动鞋商店:Hype DC
2018/03/31 全球购物
2019年Java 最常见的 面试题
2016/10/19 面试题
应届毕业生的个人自我鉴定
2013/10/24 职场文书
广告传媒专业应届生求职信
2014/03/01 职场文书
死亡证明书样本说明
2014/10/18 职场文书
企业党建工作总结2015
2015/05/26 职场文书
医院病假条范文
2015/08/17 职场文书
只用20行Python代码实现屏幕录制功能
2021/06/02 Python
springcloud之Feign超时问题的解决
2021/06/24 Java/Android
redis requires ruby version2.2.2的解决方案
2021/07/15 Redis
原生JS实现分页
2022/04/19 Javascript