前几天弄了下django的图片上传,上传之后还需要做些简单的处理,python中PIL模块就是专门用来做这个事情的。

于是照葫芦画瓢做了几个常用图片操作,在这里记录下,以便备用。

这里有个字体文件,大家可以在自己的系统中选取一个,我这打包放在网盘中  下载

一 图样

原始图片

操作一: 缩略图(通常不用这个方式,因为图片质量损坏太大)

操作二 : 旋转图片中的某一部分

操作三: 给图片添加一个图片水印, 2张图层合并

     

操作四: 给图片添加文字水印,这个用的比较多, 我这里弄了个白色通明低,可以弄成完全透明的

操作 五 等比压缩(比较适合做缩略图)

操作六 按照比例剪裁之后,等比压缩,有时候需要定比例的图片可以这么做

二 代码

# -*- encoding=utf-8 -*-
'''
author: orangleliu
pil处理图片,验证,处理
大小,格式 过滤
压缩,截图,转换

图片库最好用Pillow
还有一个测试图片test.jpg, 一个log图片,一个字体文件
'''

#图片的基本参数获取
try:
    from PIL import Image, ImageDraw, ImageFont, ImageEnhance
except ImportError:
    import Image, ImageDraw, ImageFont, ImageEnhance

def compress_image(img, w=128, h=128):
    '''
    缩略图
    '''
    img.thumbnail((w,h))
    im.save('test1.png', 'PNG')
    print u'成功保存为png格式, 压缩为128*128格式图片'

def cut_image(img):
    '''
    截图, 旋转,再粘贴
    '''
    #eft, upper, right, lower
    #x y z w  x,y 是起点, z,w是偏移值
    width, height = img.size
    box = (width-200, height-100, width, height)
    region = img.crop(box)
    #旋转角度
    region = region.transpose(Image.ROTATE_180)
    img.paste(region, box)
    img.save('test2.jpg', 'JPEG')
    print u'重新拼图成功'

def logo_watermark(img, logo_path):
    '''
    添加一个图片水印,原理就是合并图层,用png比较好
    '''
    baseim = img
    logoim = Image.open(logo_path)
    bw, bh = baseim.size
    lw, lh = logoim.size
    baseim.paste(logoim, (bw-lw, bh-lh))
    baseim.save('test3.jpg', 'JPEG')
    print u'logo水印组合成功'

def text_watermark(img, text, out_file="test4.jpg", angle=23, opacity=0.50):
    '''
    添加一个文字水印,做成透明水印的模样,应该是png图层合并
    http://www.pythoncentral.io/watermark-images-python-2x/
    这里会产生著名的 ImportError("The _imagingft C module is not installed") 错误
    Pillow通过安装来解决 pip install Pillow
    '''
    watermark = Image.new('RGBA', img.size, (255,255,255)) #我这里有一层白色的膜,去掉(255,255,255) 这个参数就好了

    FONT = "msyh.ttf"
    size = 2

    n_font = ImageFont.truetype(FONT, size)                                       #得到字体
    n_width, n_height = n_font.getsize(text)
    text_box = min(watermark.size[0], watermark.size[1])
    while (n_width+n_height <  text_box):
        size += 2
        n_font = ImageFont.truetype(FONT, size=size)
        n_width, n_height = n_font.getsize(text)                                   #文字逐渐放大,但是要小于图片的宽高最小值

    text_width = (watermark.size[0] - n_width) / 2
    text_height = (watermark.size[1] - n_height) / 2
    #watermark = watermark.resize((text_width,text_height), Image.ANTIALIAS)
    draw = ImageDraw.Draw(watermark, 'RGBA')                                       #在水印层加画笔
    draw.text((text_width,text_height),
              text, font=n_font, fill="#21ACDA")
    watermark = watermark.rotate(angle, Image.BICUBIC)
    alpha = watermark.split()[3]
    alpha = ImageEnhance.Brightness(alpha).enhance(opacity)
    watermark.putalpha(alpha)
    Image.composite(watermark, img, watermark).save(out_file, 'JPEG')
    print u"文字水印成功"

#等比例压缩图片
def resizeImg(img, dst_w=0, dst_h=0, qua=85):
    '''
    只给了宽或者高,或者两个都给了,然后取比例合适的
    如果图片比给要压缩的尺寸都要小,就不压缩了
    '''
    ori_w, ori_h = im.size
    widthRatio = heightRatio = None
    ratio = 1

    if (ori_w and ori_w > dst_w) or (ori_h and ori_h  > dst_h):
        if dst_w and ori_w > dst_w:
            widthRatio = float(dst_w) / ori_w                                      #正确获取小数的方式
        if dst_h and ori_h > dst_h:
            heightRatio = float(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("test5.jpg", "JPEG", quality=qua)
    print u'等比压缩完成'

    '''
    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(im, dst_w, dst_h, qua=95):
    '''
        先按照一个比例对图片剪裁,然后在压缩到指定尺寸
        一个图片 16:5 ,压缩为 2:1 并且宽为200,就要先把图片裁剪成 10:5,然后在等比压缩
    '''
    ori_w,ori_h = im.size

    dst_scale = float(dst_w) / dst_h  #目标高宽比
    ori_scale = float(ori_w) / ori_h #原高宽比

    if ori_scale <= dst_scale:
        #过高
        width = ori_w
        height = int(width/dst_scale)

        x = 0
        y = (ori_h - height) / 2

    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(dst_w) / width
    newWidth = int(width * ratio)
    newHeight = int(height * ratio)
    newIm.resize((newWidth,newHeight),Image.ANTIALIAS).save("test6.jpg", "JPEG",quality=95)
    print  "old size  %s  %s"%(ori_w, ori_h)
    print  "new size %s %s"%(newWidth, newHeight)
    print u"剪裁后等比压缩完成"

if __name__ == "__main__":
    '''
    主要是实现功能, 代码没怎么整理
    '''
    im = Image.open('test.jpg')  #image 对象
    compress_image(im)

    im = Image.open('test.jpg')  #image 对象
    cut_image(im)

    im = Image.open('test.jpg')  #image 对象
    logo_watermark(im, 'logo.png')

    im = Image.open('test.jpg')  #image 对象
    text_watermark(im, 'Orangleliu')

    im = Image.open('test.jpg')  #image 对象
    resizeImg(im, dst_w=100, qua=85)

    im = Image.open('test.jpg')  #image 对象
    clipResizeImg(im, 100, 200)

三 参考


[Python] 图像简单处理(PIL or Pillow)的更多相关文章

  1. 第一篇 Python图片处理模块PIL(pillow)

    本篇包含:一.Image类的属性:1.Format   2.Mode   3.Size    4.Palette    5.Info                   二.类的函数:1.New   ...

  2. 第二篇 Python图片处理模块PIL(pillow)

    本篇包含:16.Point    17.Putalpha    18.Putdata    19.Putpalette    20.Putpixel      21.Quantize     22.R ...

  3. 利用python进行简单的图像处理:包括打开,显示以及保存图像

    利用python进行简单的图像处理:包括打开,显示以及保存图像 利用PIL处理 PIL(python image library) 是python用于图片处理的package.但目前这个package ...

  4. Python PIL、Pillow笔记

    原文链接:https://blog.csdn.net/FlashKoala/article/details/90649464 一.PIL.Pillow简介 PIL(Python Imaging Lib ...

  5. PIL、Pillow安装使用方法

    PIL(Python Imaging Library)是Python常用的图像处理库,而Pillow是PIL的一个友好Fork,提供了了广泛的文件格式支持,强大的图像处理能力,主要包括图像储存.图像显 ...

  6. 利用Python实现简单的相似图片搜索的教程

    大概五年前吧,我那时还在为一家约会网站做开发工作.他们是早期创业公司,但他们也开始拥有了一些稳定用户量.不像其他约会网站,这家公司向来以洁身自好为主要市场形象.它不是一个供你鬼混的网站——是让你能找到 ...

  7. PIL库 (Pillow)

    PIL基础 *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !important ...

  8. 【Tool】Augmentor和imgaug——python图像数据增强库

    Augmentor和imgaug--python图像数据增强库 Tags: ComputerVision Python 介绍两个图像增强库:Augmentor和imgaug,Augmentor使用比较 ...

  9. PIL和Pillow

    关于Pillow与PIL PIL(Python Imaging Library)是Python一个强大方便的图像处理库,名气也比较大.不过只支持到Python 2.7. PIL官方网站:http:// ...

随机推荐

  1. 3.如何搭建Appium自动化测试环境

    整个APP自动化环境安装可以参照虫师博客安装 附以下链接: http://www.cnblogs.com/fnng/category/695788.html 下面介绍运用到工作中遇到的一些问题 1.如 ...

  2. 《C++ Primer》学习笔记:向vector对象添加元素蕴含的编程假定

    练习<C++ Primer>中的3.14节时,当敲入: #include <iostream> #include <string> using namespace ...

  3. [HNOI 2014]江南乐

    Description 题库链接 给你指定一个数 \(f\) ,并给你 \(T\) 组游戏,每组有 \(n\) 堆石子, \(A,B\) 两人轮流对石子进行操作,每次你可以选择其中任意一堆数量不小于 ...

  4. [JSOI2007]文本生成器

    题目描述 JSOI交给队员ZYX一个任务,编制一个称之为“文本生成器”的电脑软件:该软件的使用者是一些低幼人群,他们现在使用的是GW文本生成器v6版. 该软件可以随机生成一些文章―――总是生成一篇长度 ...

  5. [NOI2011]道路修建

    题目描述 在 W 星球上有 n 个国家.为了各自国家的经济发展,他们决定在各个国家 之间建设双向道路使得国家之间连通.但是每个国家的国王都很吝啬,他们只愿 意修建恰好 n – 1 条双向道路. 每条道 ...

  6. NOIP 2007树网的核

    题目描述 设T=(V, E, W) 是一个无圈且连通的无向图(也称为无根树),每条边到有正整数的权,我们称T为树网(treebetwork),其中V,E分别表示结点与边的集合,W表示各边长度的集合,并 ...

  7. hdu 5445 多重背包

    Food Problem Time Limit: 3000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)To ...

  8. bzoj 4006: [JLOI2015]管道连接

    Description 小铭铭最近进入了某情报部门,该部门正在被如何建立安全的通道连接困扰. 该部门有 n 个情报站,用 1 到 n 的整数编号.给出 m 对情报站 ui;vi 和费用 wi,表示情 ...

  9. 用Qemu运行/调试arm linux【转】

    转自:https://blog.csdn.net/absurd/article/details/78984244 用Qemu运行/调试arm linux,这事情干过好几次了,久了就忘记了,每次都要重新 ...

  10. String.IndexOf 方法笔记

    记录以备使用 作用:报告指定 Unicode 字符或字符串在此实例中的第一个匹配项的从零开始的索引. 如果未在此实例中找到该字符或字符串,则此方法返回 -1. 重载列表   名称 说明 IndexOf ...