zoukankan      html  css  js  c++  java
  • 用Python图像处理

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

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

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

    一 图样

    原始图片

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

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

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

         

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

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

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

    二 代码

    [python] view plain copy
     
    1. # -*- encoding=utf-8 -*-  
    2. ''''' 
    3. author: orangleliu 
    4. pil处理图片,验证,处理 
    5. 大小,格式 过滤 
    6. 压缩,截图,转换 
    7.  
    8. 图片库最好用Pillow 
    9. 还有一个测试图片test.jpg, 一个log图片,一个字体文件 
    10. '''  
    11.   
    12. #图片的基本参数获取  
    13. try:  
    14.     from PIL import Image, ImageDraw, ImageFont, ImageEnhance  
    15. except ImportError:  
    16.     import Image, ImageDraw, ImageFont, ImageEnhance  
    17.   
    18. def compress_image(img, w=128, h=128):  
    19.     ''''' 
    20.     缩略图 
    21.     '''  
    22.     img.thumbnail((w,h))  
    23.     im.save('test1.png', 'PNG')  
    24.     print u'成功保存为png格式, 压缩为128*128格式图片'  
    25.   
    26. def cut_image(img):  
    27.     ''''' 
    28.     截图, 旋转,再粘贴 
    29.     '''  
    30.     #eft, upper, right, lower  
    31.     #x y z w  x,y 是起点, z,w是偏移值  
    32.     width, height = img.size  
    33.     box = (width-200, height-100, width, height)  
    34.     region = img.crop(box)  
    35.     #旋转角度  
    36.     region = region.transpose(Image.ROTATE_180)  
    37.     img.paste(region, box)  
    38.     img.save('test2.jpg', 'JPEG')  
    39.     print u'重新拼图成功'  
    40.   
    41. def logo_watermark(img, logo_path):  
    42.     ''''' 
    43.     添加一个图片水印,原理就是合并图层,用png比较好 
    44.     '''  
    45.     baseim = img  
    46.     logoim = Image.open(logo_path)  
    47.     bw, bh = baseim.size  
    48.     lw, lh = logoim.size  
    49.     baseim.paste(logoim, (bw-lw, bh-lh))  
    50.     baseim.save('test3.jpg', 'JPEG')  
    51.     print u'logo水印组合成功'  
    52.   
    53. def text_watermark(img, text, out_file="test4.jpg", angle=23, opacity=0.50):  
    54.     ''''' 
    55.     添加一个文字水印,做成透明水印的模样,应该是png图层合并 
    56.     http://www.pythoncentral.io/watermark-images-python-2x/ 
    57.     这里会产生著名的 ImportError("The _imagingft C module is not installed") 错误 
    58.     Pillow通过安装来解决 pip install Pillow 
    59.     '''  
    60.     watermark = Image.new('RGBA', img.size, (255,255,255)) #我这里有一层白色的膜,去掉(255,255,255) 这个参数就好了  
    61.   
    62.     FONT = "msyh.ttf"  
    63.     size = 2  
    64.   
    65.     n_font = ImageFont.truetype(FONT, size)                                       #得到字体  
    66.     n_width, n_height = n_font.getsize(text)  
    67.     text_box = min(watermark.size[0], watermark.size[1])  
    68.     while (n_width+n_height <  text_box):  
    69.         size += 2  
    70.         n_font = ImageFont.truetype(FONT, size=size)  
    71.         n_width, n_height = n_font.getsize(text)                                   #文字逐渐放大,但是要小于图片的宽高最小值  
    72.   
    73.     text_width = (watermark.size[0] - n_width) / 2  
    74.     text_height = (watermark.size[1] - n_height) / 2  
    75.     #watermark = watermark.resize((text_width,text_height), Image.ANTIALIAS)  
    76.     draw = ImageDraw.Draw(watermark, 'RGBA')                                       #在水印层加画笔  
    77.     draw.text((text_width,text_height),  
    78.               text, font=n_font, fill="#21ACDA")  
    79.     watermark = watermark.rotate(angle, Image.BICUBIC)  
    80.     alpha = watermark.split()[3]  
    81.     alpha = ImageEnhance.Brightness(alpha).enhance(opacity)  
    82.     watermark.putalpha(alpha)  
    83.     Image.composite(watermark, img, watermark).save(out_file, 'JPEG')  
    84.     print u"文字水印成功"  
    85.   
    86.   
    87. #等比例压缩图片  
    88. def resizeImg(img, dst_w=0, dst_h=0, qua=85):  
    89.     ''''' 
    90.     只给了宽或者高,或者两个都给了,然后取比例合适的 
    91.     如果图片比给要压缩的尺寸都要小,就不压缩了 
    92.     '''  
    93.     ori_w, ori_h = im.size  
    94.     widthRatio = heightRatio = None  
    95.     ratio = 1  
    96.   
    97.     if (ori_w and ori_w > dst_w) or (ori_h and ori_h  > dst_h):  
    98.         if dst_w and ori_w > dst_w:  
    99.             widthRatio = float(dst_w) / ori_w                                      #正确获取小数的方式  
    100.         if dst_h and ori_h > dst_h:  
    101.             heightRatio = float(dst_h) / ori_h  
    102.   
    103.         if widthRatio and heightRatio:  
    104.             if widthRatio < heightRatio:  
    105.                 ratio = widthRatio  
    106.             else:  
    107.                 ratio = heightRatio  
    108.   
    109.         if widthRatio and not heightRatio:  
    110.             ratio = widthRatio  
    111.   
    112.         if heightRatio and not widthRatio:  
    113.             ratio = heightRatio  
    114.   
    115.         newWidth = int(ori_w * ratio)  
    116.         newHeight = int(ori_h * ratio)  
    117.     else:  
    118.         newWidth = ori_w  
    119.         newHeight = ori_h  
    120.   
    121.     im.resize((newWidth,newHeight),Image.ANTIALIAS).save("test5.jpg", "JPEG", quality=qua)  
    122.     print u'等比压缩完成'  
    123.   
    124.     ''''' 
    125.     Image.ANTIALIAS还有如下值: 
    126.     NEAREST: use nearest neighbour 
    127.     BILINEAR: linear interpolation in a 2x2 environment 
    128.     BICUBIC:cubic spline interpolation in a 4x4 environment 
    129.     ANTIALIAS:best down-sizing filter 
    130.     '''  
    131.   
    132. #裁剪压缩图片  
    133. def clipResizeImg(im, dst_w, dst_h, qua=95):  
    134.     ''''' 
    135.         先按照一个比例对图片剪裁,然后在压缩到指定尺寸 
    136.         一个图片 16:5 ,压缩为 2:1 并且宽为200,就要先把图片裁剪成 10:5,然后在等比压缩 
    137.     '''  
    138.     ori_w,ori_h = im.size  
    139.   
    140.     dst_scale = float(dst_w) / dst_h  #目标高宽比  
    141.     ori_scale = float(ori_w) / ori_h #原高宽比  
    142.   
    143.     if ori_scale <= dst_scale:  
    144.         #过高  
    145.         width = ori_w  
    146.         height = int(width/dst_scale)  
    147.   
    148.         x = 0  
    149.         y = (ori_h - height) / 2  
    150.   
    151.     else:  
    152.         #过宽  
    153.         height = ori_h  
    154.         width = int(height*dst_scale)  
    155.   
    156.         x = (ori_w - width) / 2  
    157.         y = 0  
    158.   
    159.     #裁剪  
    160.     box = (x,y,width+x,height+y)  
    161.     #这里的参数可以这么认为:从某图的(x,y)坐标开始截,截到(width+x,height+y)坐标  
    162.     #所包围的图像,crop方法与php中的imagecopy方法大为不一样  
    163.     newIm = im.crop(box)  
    164.     im = None  
    165.   
    166.     #压缩  
    167.     ratio = float(dst_w) / width  
    168.     newWidth = int(width * ratio)  
    169.     newHeight = int(height * ratio)  
    170.     newIm.resize((newWidth,newHeight),Image.ANTIALIAS).save("test6.jpg", "JPEG",quality=95)  
    171.     print  "old size  %s  %s"%(ori_w, ori_h)  
    172.     print  "new size %s %s"%(newWidth, newHeight)  
    173.     print u"剪裁后等比压缩完成"  
    174.   
    175.   
    176. if __name__ == "__main__":  
    177.     ''''' 
    178.     主要是实现功能, 代码没怎么整理 
    179.     '''  
    180.     im = Image.open('test.jpg')  #image 对象  
    181.     compress_image(im)  
    182.   
    183.     im = Image.open('test.jpg')  #image 对象  
    184.     cut_image(im)  
    185.   
    186.     im = Image.open('test.jpg')  #image 对象  
    187.     logo_watermark(im, 'logo.png')  
    188.   
    189.     im = Image.open('test.jpg')  #image 对象  
    190.     text_watermark(im, 'Orangleliu')  
    191.   
    192.     im = Image.open('test.jpg')  #image 对象  
    193.     resizeImg(im, dst_w=100, qua=85)  
    194.   
    195.     im = Image.open('test.jpg')  #image 对象  
    196.     clipResizeImg(im, 100, 200)  



    三 参考

     
  • 相关阅读:
    opencv和linux的关联
    附加数据库 对于server XXX失败
    android.app.Dialog(23)里window的那些事(坑)
    hdu 4722 Good Numbers(数位dp)
    Java程序猿必知的10个调试技巧
    iir调试记录
    在Scope利用Content sharing Widget来分享内容
    JavaEE 技术选型建议,server配置,部署策略
    x265探索与研究(四):怎样编码视频?
    计算git树上随意两点的近期切割点。
  • 原文地址:https://www.cnblogs.com/jyxbk/p/7776627.html
Copyright © 2011-2022 走看看