python图片添加水印(转载)
转载来自:http://blog.csdn.net/orangleliu/
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)