python圖片添加水印(轉載)

轉載來自: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)  
相關文章
相關標籤/搜索