用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)  



 

三 參考

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM