不知道别人是怎么做的,闲着无聊就根据前几天看到的一些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)

效果如下:

其他水印图:

python水印倾斜_【python PIL学习】给照片打水印相关推荐

  1. 0基础学好python难不难_零基础学习Python难不难?Python有什么优势?

    原标题:零基础学习Python难不难?Python有什么优势? Python是一种计算机程序设计语言.首先,我们普及一下编程语言的基础知识.用任何编程语言来开发程序,都是为了让计算机干活,比如下载一个 ...

  2. python keyboard模块_[python] PyMouse、PyKeyboard用python操作鼠标和键盘

    1.PyUserInput 简介 PyUserInput是一个使用python的跨平台的操作鼠标和键盘的模块,非常方便使用.支持的平台及依赖如下: Linux - Xlib Mac - Quartz, ...

  3. python 病毒 基因_#Python#提取基因对应的蛋白质名

    提取基因对应的蛋白质官方名 最开始,是需要将基因跟其编码的蛋白质对应起来,找遍了各种数据库都没发现有相关的注释文件,Uniprot作为处理蛋白质的大佬,结果里都有,肯定有办法能够满足需求. 搜索TP5 ...

  4. 从零开始学python人工智能课程_从零开始如何学习人工智能?

    想要学习人工智能?这里有一条完整路径资源 在本文中,<Analytics India>杂志给出了学习AI的最佳途径.... 科技领域的天平正在向人工智能倾斜,IT领域的技术人员正在将AI应 ...

  5. python商业爬虫_商业爬虫学习笔记day1

    day1 一. HTTP 1.介绍: https://www.cnblogs.com/vamei/archive/2013/05/11/3069788.html http://blog.csdn.ne ...

  6. 明日科技的python书籍怎么样_零基础学习Python不可错过的5本书籍

    3.Python基础教程(第3版) 作者:[挪]芒努斯·利·海特兰德(Magnus Lie Hetland) 出版社:人民邮电出版社 Python3.5编程从入门到实践,Python入门佳作,机器学习 ...

  7. python 分班_小白如何学习python

    Python 是一种面向对象.解释型计算机程序设计语言,由Guido van Rossum 于1989年底发明,第一个公开发行版发行于1991年,Python 源代码同样遵循GPL(GNU Gener ...

  8. python数据参数_零基础学习python数据分析——函数的参数

    原标题:零基础学习python数据分析--函数的参数 上一节课中我们讲了python的函数定义,Python的函数定义非常简单,但灵活度却非常大.除了正常定义的必选参数外,还可以使用默认参数.可变参数 ...

  9. python计算机图形学_图形图像学习随笔:计算机图形学的一些基本概念

    本文内容摘抄于:<计算机图形学的概念> 一.计算机图形学的范畴 1.图形主要分为两类,一类是基于线条信息表示的,如工程图.等高线地形图.曲面的线框图等:另一类是明暗图,也就是通常所说的真实 ...

最新文章

  1. oracle 监听数据交互
  2. 扫码点餐小程序源码_扫码点餐小程序有什么用?怎么制作?
  3. python图片转字符画
  4. 《VMware、Citrix和Microsoft虚拟化技术详解与应用实践》一2.4 ESXi 5.0的简单设置...
  5. Spring的新注解——Configuration、ComponentScan、Bean、Import、PropertySource || spring整合Junit分析
  6. 都江堰很美-佩服古人_Crmhf的一天
  7. 《linux 网卡别名的添加和绑定》RHEL6
  8. oracle 10 数据库覆盖
  9. mxnet window10 cpu 模式的安装
  10. Python的PyDBG调试器的用法
  11. ubuntu 18.04 设置中文输入法
  12. zoj 3229 Shoot the Bullet(无源汇上下界最大流)
  13. Ubuntu18.04下安装配置ORB_SLAM2以及过程中遇到的问题解决方法
  14. Python 用下划线作为变量前缀和后缀指定特殊变量
  15. 【基础教程】免疫算法【006期】
  16. java 动画 制作_DragonBones简单动画制作实例
  17. Listview刷新数据
  18. 电脑上游戏视频录制的方法
  19. java dns缓存清理_jvm dns缓存问题解决方式
  20. 第三方支付机构是如何产生的?有着怎样的历史背景?它的未来又该如何去走得更加辉煌?

热门文章

  1. ACL 2021 Question Answering
  2. GoLang之使用sync.Cond
  3. 数据中心机房监控室效果图
  4. 利用SOP激活沉默用户
  5. vue3+ts 实现文件在线预览
  6. color model(颜色模型/色彩模型)
  7. python如何定义一个函数选择题_Python逻辑题(以下10个选择题有唯一答案,请编写自定义函数judge遍历答案列表并报告正确答案),python,道,汇报...
  8. FFplay文档解读-16-音频过滤器一
  9. js判断苹果ios各类机型
  10. Vue2源码的学习日记(3)