轉載來自:http://blog.csdn.net/orangleliu/php
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) # -*- encoding=utf-8 -*- 197 ''''' 198 author: orangleliu 199 pil處理圖片,驗證,處理 200 大小,格式 過濾 201 壓縮,截圖,轉換 202 203 圖片庫最好用Pillow 204 還有一個測試圖片test.jpg, 一個log圖片,一個字體文件 205 ''' 206 207 #圖片的基本參數獲取 208 try: 209 from PIL import Image, ImageDraw, ImageFont, ImageEnhance 210 except ImportError: 211 import Image, ImageDraw, ImageFont, ImageEnhance 212 213 def compress_image(img, w=128, h=128): 214 ''''' 215 縮略圖 216 ''' 217 img.thumbnail((w,h)) 218 im.save('test1.png', 'PNG') 219 print u'成功保存爲png格式, 壓縮爲128*128格式圖片' 220 221 def cut_image(img): 222 ''''' 223 截圖, 旋轉,再粘貼 224 ''' 225 #eft, upper, right, lower 226 #x y z w x,y 是起點, z,w是偏移值 227 width, height = img.size 228 box = (width-200, height-100, width, height) 229 region = img.crop(box) 230 #旋轉角度 231 region = region.transpose(Image.ROTATE_180) 232 img.paste(region, box) 233 img.save('test2.jpg', 'JPEG') 234 print u'從新拼圖成功' 235 236 def logo_watermark(img, logo_path): 237 ''''' 238 添加一個圖片水印,原理就是合併圖層,用png比較好 239 ''' 240 baseim = img 241 logoim = Image.open(logo_path) 242 bw, bh = baseim.size 243 lw, lh = logoim.size 244 baseim.paste(logoim, (bw-lw, bh-lh)) 245 baseim.save('test3.jpg', 'JPEG') 246 print u'logo水印組合成功' 247 248 def text_watermark(img, text, out_file="test4.jpg", angle=23, opacity=0.50): 249 ''''' 250 添加一個文字水印,作成透明水印的模樣,應該是png圖層合併 251 http://www.pythoncentral.io/watermark-images-python-2x/ 252 這裏會產生著名的 ImportError("The _imagingft C module is not installed") 錯誤 253 Pillow經過安裝來解決 pip install Pillow 254 ''' 255 watermark = Image.new('RGBA', img.size, (255,255,255)) #我這裏有一層白色的膜,去掉(255,255,255) 這個參數就行了 256 257 FONT = "msyh.ttf" 258 size = 2 259 260 n_font = ImageFont.truetype(FONT, size) #獲得字體 261 n_width, n_height = n_font.getsize(text) 262 text_box = min(watermark.size[0], watermark.size[1]) 263 while (n_width+n_height < text_box): 264 size += 2 265 n_font = ImageFont.truetype(FONT, size=size) 266 n_width, n_height = n_font.getsize(text) #文字逐漸放大,可是要小於圖片的寬高最小值 267 268 text_width = (watermark.size[0] - n_width) / 2 269 text_height = (watermark.size[1] - n_height) / 2 270 #watermark = watermark.resize((text_width,text_height), Image.ANTIALIAS) 271 draw = ImageDraw.Draw(watermark, 'RGBA') #在水印層加畫筆 272 draw.text((text_width,text_height), 273 text, font=n_font, fill="#21ACDA") 274 watermark = watermark.rotate(angle, Image.BICUBIC) 275 alpha = watermark.split()[3] 276 alpha = ImageEnhance.Brightness(alpha).enhance(opacity) 277 watermark.putalpha(alpha) 278 Image.composite(watermark, img, watermark).save(out_file, 'JPEG') 279 print u"文字水印成功" 280 281 282 #等比例壓縮圖片 283 def resizeImg(img, dst_w=0, dst_h=0, qua=85): 284 ''''' 285 只給了寬或者高,或者兩個都給了,而後取比例合適的 286 若是圖片比給要壓縮的尺寸都要小,就不壓縮了 287 ''' 288 ori_w, ori_h = im.size 289 widthRatio = heightRatio = None 290 ratio = 1 291 292 if (ori_w and ori_w > dst_w) or (ori_h and ori_h > dst_h): 293 if dst_w and ori_w > dst_w: 294 widthRatio = float(dst_w) / ori_w #正確獲取小數的方式 295 if dst_h and ori_h > dst_h: 296 heightRatio = float(dst_h) / ori_h 297 298 if widthRatio and heightRatio: 299 if widthRatio < heightRatio: 300 ratio = widthRatio 301 else: 302 ratio = heightRatio 303 304 if widthRatio and not heightRatio: 305 ratio = widthRatio 306 307 if heightRatio and not widthRatio: 308 ratio = heightRatio 309 310 newWidth = int(ori_w * ratio) 311 newHeight = int(ori_h * ratio) 312 else: 313 newWidth = ori_w 314 newHeight = ori_h 315 316 im.resize((newWidth,newHeight),Image.ANTIALIAS).save("test5.jpg", "JPEG", quality=qua) 317 print u'等比壓縮完成' 318 319 ''''' 320 Image.ANTIALIAS還有以下值: 321 NEAREST: use nearest neighbour 322 BILINEAR: linear interpolation in a 2x2 environment 323 BICUBIC:cubic spline interpolation in a 4x4 environment 324 ANTIALIAS:best down-sizing filter 325 ''' 326 327 #裁剪壓縮圖片 328 def clipResizeImg(im, dst_w, dst_h, qua=95): 329 ''''' 330 先按照一個比例對圖片剪裁,而後在壓縮到指定尺寸 331 一個圖片 16:5 ,壓縮爲 2:1 而且寬爲200,就要先把圖片裁剪成 10:5,而後在等比壓縮 332 ''' 333 ori_w,ori_h = im.size 334 335 dst_scale = float(dst_w) / dst_h #目標高寬比 336 ori_scale = float(ori_w) / ori_h #原高寬比 337 338 if ori_scale <= dst_scale: 339 #太高 340 width = ori_w 341 height = int(width/dst_scale) 342 343 x = 0 344 y = (ori_h - height) / 2 345 346 else: 347 #過寬 348 height = ori_h 349 width = int(height*dst_scale) 350 351 x = (ori_w - width) / 2 352 y = 0 353 354 #裁剪 355 box = (x,y,width+x,height+y) 356 #這裏的參數能夠這麼認爲:從某圖的(x,y)座標開始截,截到(width+x,height+y)座標 357 #所包圍的圖像,crop方法與php中的imagecopy方法大爲不同 358 newIm = im.crop(box) 359 im = None 360 361 #壓縮 362 ratio = float(dst_w) / width 363 newWidth = int(width * ratio) 364 newHeight = int(height * ratio) 365 newIm.resize((newWidth,newHeight),Image.ANTIALIAS).save("test6.jpg", "JPEG",quality=95) 366 print "old size %s %s"%(ori_w, ori_h) 367 print "new size %s %s"%(newWidth, newHeight) 368 print u"剪裁後等比壓縮完成" 369 370 371 if __name__ == "__main__": 372 ''''' 373 主要是實現功能, 代碼沒怎麼整理 374 ''' 375 im = Image.open('test.jpg') #image 對象 376 compress_image(im) 377 378 im = Image.open('test.jpg') #image 對象 379 cut_image(im) 380 381 im = Image.open('test.jpg') #image 對象 382 logo_watermark(im, 'logo.png') 383 384 im = Image.open('test.jpg') #image 對象 385 text_watermark(im, 'Orangleliu') 386 387 im = Image.open('test.jpg') #image 對象 388 resizeImg(im, dst_w=100, qua=85) 389 390 im = Image.open('test.jpg') #image 對象 391 clipResizeImg(im, 100, 200)