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)