【python PIL学习】给照片打水印

不知道别人是怎么做的,闲着无聊就根据前几天看到的一些PIL里面的函数,写了这个小程序,经过测试,基本可以给所有像宽400以上的图片打上从左下到右上的看上去质量尚可的水印,更小的图片水印偏下。写完觉得很简单,还是写出来记录一下,唔,我现在仍然很无聊。

我的思路很简单:

  • 一个比较大的空白图像上添加文字(为什么比较大呢,因为图像旋转之后一不小心会截取出界)
  • 旋转写过字的空白图像
  • 截取空白图像中的文字部分(为什么要截取呢,因为旋转过后的图像直接与需要水印的图像合并,整个图像都会是旋转状态,达不到水印倾斜的效果,所以把倾斜的文字图像截取成一个文字倾斜但是整体水平的图像)
  • 将截取到的文字部分粘贴在与要水印的图像大小相等的另一个空白图像上(为什么要粘贴呢,因为要合并的两个图像尺寸必须相同)
  • 将被粘贴过的图像与要水印的图像按照较低的alpha合并
好吧,讲得有点乱,下面一点点看看我的程序以及示例吧:

1、第一部分,主要是程序要用到的库的调用,以及需要的基本信息初始化,如下:

import Image
import ImageDraw
import ImageFont
import math

fileName = input("Please input your iamge name:") #输入要打水印的图片名称
text = input("Please input your text to ink:")    #输入要打得水印
im = Image.open(fileName)                         #打开要打水印的相片

imageW,imageH = im.size         #获取图片尺寸
textImageW = int(imageW*1.5)    #确定写文字图片的尺寸,如前所述,要比照片大,我取1.5倍
textImageH = int(imageH*1.5)
blank = Image.new("RGB",(textImageW,textImageH),"white")  #创建用于添加文字的空白图像
d = ImageDraw.Draw(blank)                                 #创建draw对象

2、第二部分,根据图片大小确定打水印的文字大小。对于不同大小的相片,如果添加水印过大,甚至不能全部显示,或者过小都不美观。但是像素值与字号之间的对应关系我不知道是否有直接的工具可以实现,问了许久也没有办法解决,于是选择了最拙劣的分区赋值。还好最后测试的效果还算可以,只是图片过小的时候会稍稍偏下,不过像宽400以上基本上没有问题

if imageW < 400:
    k = 32
elif imageW < 600:
    k = 48
elif imageW < 800:
    k = 64
elif imageW < 1000:
    k = 80
elif imageW < 1200:
    k = 100
elif imageW < 1400:
    k =128
elif imageW < 1800:
    k= 156
elif imageW < 2200:
    k = 192
elif imageW < 2600:
    k = 256
elif imageW < 3100:
    k = 300
print "fontsize:",k

3、在空白图片上添加文字。为了实现更好的裁剪,我将文字写在空白图像的正中间

Font = ImageFont.truetype("C:\Windows\Fonts\SHOWG.TTF",k)  #创建Font对象,k之为字号
textW,textH = Font.getsize(text)            #获取文字尺寸
d.ink = 0 + 0 * 256 + 0 * 256 * 256         #黑色
d.text([(textImageW-textW)/2,(textImageH-textH)/2],text,font = Font)#将文字写在空白图像正中间
效果如下:

效果如下:

4、旋转图像,实现文字倾斜

#旋转文字
textRotate = blank.rotate(30)
#textRotate.show()
效果如下:
效果如下:

从上图可以看出,旋转后的图像周围会有黑色背景,所以如果截取尺寸过大,四个角度会有阴影遗留下来印到图片上。故前面我选用比相片更大尺寸的空白图像添加文字。

5、截取文字区域。要从上图中截取出最大的不触及黑色背景的图片,可以根据旋转角度以及图像尺寸计算出,可截取的最大尺寸,方法如下:

rLen = math.sqrt((textW/2)**2+(textH/2)**2)   
oriAngle = math.atan(textH/textW)
cropW = rLen*math.cos(oriAngle + math.pi/6) *2   #被截取区域的宽高
cropH = rLen*math.sin(oriAngle + math.pi/6) *2
box = [int((textImageW-cropW)/2-1),int((textImageH-cropH)/2-1)-50,int((textImageW+cropW)/2+1),int((textImageH+cropH)/2+1)]
textIm = textRotate.crop(box)  #截取文字图片
效果如下:

效果如下:

6、截取后的图片贴在另一个跟相片尺寸相同的空白图像上。达到比较好的效果,要粘贴在空白图像的正中央

pasteW,pasteH = textIm.size
#旋转后的文字图片粘贴在一个新的blank图像上
textBlank = Image.new("RGB",(imageW,imageH),"white")
pasteBox = (int((imageW-pasteW)/2-1),int((imageH-pasteH)/2-1))
textBlank.paste(textIm,pasteBox)


效果如下:

效果如下:

7、图像合并,水印完成。可改变alpha值,改变水印的深浅程度

waterImage = Image.blend(im,textBlank,0.2)
效果如下:
效果如下:


其他水印图:

其他水印图

1




  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要在图片上添加数字水印,可以使用PythonPIL库(Python Imaging Library),具体步骤如下: 1.导入PIL库 ```python from PIL import Image, ImageDraw, ImageFont ``` 2.打开图片 ```python im = Image.open('image.jpg') ``` 3.创建字体对象 ```python font = ImageFont.truetype('arial.ttf', size=20) ``` 4.创建Draw对象 ```python draw = ImageDraw.Draw(im) ``` 5.添加水印 ```python draw.text((0, 0), '123', fill=(255, 0, 0), font=font) ``` 6.保存图片 ```python im.save('watermark.jpg') ``` 为了检测数字水印是否被修改或删除,可以使用数字水印算法。一种常见的数字水印算法是LSB(Least Significant Bit)算法,即将数字水印嵌入到图片的最低有效位中。具体步骤如下: 1.将数字水印转换为二进制序列 ```python watermark = '123' watermark_binary = ''.join(format(ord(c), '08b') for c in watermark) ``` 2.打开图片 ```python im = Image.open('watermark.jpg') ``` 3.将图片转换为像素矩阵 ```python pixels = im.load() width, height = im.size ``` 4.将数字水印嵌入到最低有效位中 ```python index = 0 for y in range(height): for x in range(width): r, g, b = pixels[x, y] if index < len(watermark_binary): r_binary = format(r, '08b') r_binary = r_binary[:-1] + watermark_binary[index] r = int(r_binary, 2) pixels[x, y] = (r, g, b) index += 1 else: break else: continue break ``` 5.保存图片 ```python im.save('watermark_modified.jpg') ``` 6.检测数字水印是否被修改或删除 ```python im_modified = Image.open('watermark_modified.jpg') pixels_modified = im_modified.load() width_modified, height_modified = im_modified.size index = 0 watermark_binary_modified = '' for y in range(height_modified): for x in range(width_modified): r_modified, g_modified, b_modified = pixels_modified[x, y] r_binary_modified = format(r_modified, '08b') watermark_binary_modified += r_binary_modified[-1] index += 1 if index == len(watermark_binary): break else: continue break watermark_modified = ''.join(chr(int(watermark_binary_modified[i:i+8], 2)) for i in range(0, len(watermark_binary_modified), 8)) if watermark == watermark_modified: print('数字水印未被修改或删除') else: print('数字水印已被修改或删除') ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值