• 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)  
  • 相关阅读:
    面试开发需要准备的
    多线程 多进程
    TCP/IP协议学习
    深信服算法岗实习面试经验
    TZOJ4777: 方格取数
    Python 基于 NLP 的文本分类
    mac os 使用记录
    字节跳动游戏开发岗题目
    mac进行acm(C/C++)编程
    常用的正则表达式(转)
  • 原文地址:https://www.cnblogs.com/xiaoyaowuming/p/6117667.html
Copyright © 2020-2023  润新知