Python实现图片批量加入水印代码实例


Posted in Python onNovember 30, 2019

这篇文章主要介绍了Python实现图片批量加入水印代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

写文章的时候可以设置是否添加水印。可是,有些图片可能想加水印,有些不想加水印,该怎么办呢?

配置环境

python3 + pillow

pip3 install pillow

引入库

from PIL import Image, ImageSequence
import os
import random

效果预览:

Python实现图片批量加入水印代码实例

使用方法:

  • 在脚本同目录下添加水印图片 logo.png
  • 创建目录 input 并在放入要添加水印的图片
  • 创建目录 output 执行脚本 addlogo.py
  • 结果输出在 output 文件夹下

Python实现图片批量加入水印代码实例

实现原理

水印图片采集:

先读取水印图片的像素点信息和大小信息。去除透明度为0的像素,并修改透明度像素信息。

img_logo = Image.open("logo.png")
img_logo_width, img_logo_height = img_logo.size
img_logo_pixels = dict()
for w in range(img_logo_width):
  for h in range(img_logo_height):
    c = img_logo.getpixel((w,h))
    if c!=(0, 0, 0, 0):
      img_logo_pixels[(w, h)] = c[:3]+(125,)

混合颜色:

对每一个像素点采取颜色混合,其中c1是源图片的像素点信息(r,g,b,a),c2是logo图片像素点的信息。混合算法如下:

def blendPixel(c1,c2):
  a1=256-c2[3]
  a2=c2[3]-(a1*c2[3])/256.0
  a=a1+a2
  c=(int((a1*c1[0] + a2*c2[0])/a), int((a1*c1[1] + a2*c2[1])/a), int((a1*c1[2] + a2*c2[2])/a),int(a))
  return c

处理源 Image 对象:

随机一个位置开始处理像素,具体代码参考如下。

def dealOneImage(image,offX=None,offY=None):
  w, h = image.size
  offX = offX if offX else random.random();
  offY = offY if offY else random.random();
  #如果图片尺寸小于水印图片,不加水印
  if w>=img_logo_width and h>=img_logo_height:
    top = int((w - img_logo_width)*offX)
    left = int((h - img_logo_height)*offY)
    for p, c in img_logo_pixels.items():
      p_x = (p[0]+top)
      p_y = (p[1]+left)
      image_c = image.getpixel((p_x,p_y))
      if(isinstance(image_c, tuple) and len(image_c)>2):
        image.putpixel((p_x, p_y), blendPixel(image_c,c))
  return image;

处理单个文件:

对于 gif 文件先拆成一张一张图片,在图片上添加水印,最后再合成 gif 。对于其他格式的图片文件可以多添加几个水印。最后输出保存到 output 文件夹下。

def dealOneFile(filePath):
  img_orign = Image.open(filePath)
  _,file_type = os.path.splitext(filePath)
  basename = os.path.basename(filePath)
  if file_type == '.gif':
    sequence = [];
    offX=random.random()
    offY=random.random()
    for f in ImageSequence.Iterator(img_orign):
      if len(sequence) % 2 == 0:
        offX=random.random()
        offY=random.random()
      sequence.append(dealOneImage(f.convert(),offX,offY))
    sequence[0].save(f'./output/{basename}', save_all=True, append_images=sequence[1:])
  else:
    image_out = (dealOneImage(img_orign))
    for x in range(1):
      image_out = (dealOneImage(image_out))
    image_out.save(f'./output/{basename}')

处理目录:

对当前目录下的文件做一个筛选,只选取图片格式的文件。

def dealSrc(srcDir):
  picFiles = [os.path.join(srcDir,fn) for fn in os.listdir(srcDir) if fn.endswith(('.gif', '.jpg', '.png','.jpeg'))]
  for filePath in picFiles:
    dealOneFile(filePath)

小结

添加水印主要用了 python3 中的 pillow 库来实现。 首先是读取 logo 图片信息,接着在随机一个位置添加混合后的像素点信息,最后再保存起来。

其中,对于 gif 文件的处理是拆帧,再添加水印,最后再组合成一个 gif。这个只能对应比较小的 gif 文件处理,如果有更好的方法欢迎留言交流分享!

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python 不关闭控制台的实现方法
Oct 23 Python
DJANGO-ALLAUTH社交用户系统的安装配置
Nov 18 Python
Python实现拼接多张图片的方法
Dec 01 Python
利用标准库fractions模块让Python支持分数类型的方法详解
Aug 11 Python
在VS Code上搭建Python开发环境的方法
Apr 06 Python
python pandas 如何替换某列的一个值
Jun 09 Python
使用python socket分发大文件的实现方法
Jul 08 Python
python增加图像对比度的方法
Jul 12 Python
Python一行代码解决矩阵旋转的问题
Nov 30 Python
Django中从mysql数据库中获取数据传到echarts方式
Apr 07 Python
Selenium基于PIL实现拼接滚动截图
Apr 10 Python
python基础之类方法和静态方法
Oct 24 Python
Python实现把多维数组展开成DataFrame
Nov 30 #Python
Python散点图与折线图绘制过程解析
Nov 30 #Python
Python OpenCV视频截取并保存实现代码
Nov 30 #Python
解决os.path.isdir() 判断文件夹却返回false的问题
Nov 29 #Python
windows环境中利用celery实现简单任务队列过程解析
Nov 29 #Python
基于Python中isfile函数和isdir函数使用详解
Nov 29 #Python
python os.path.isfile 的使用误区详解
Nov 29 #Python
You might like
PHP3 safe_mode 失效漏洞
2006/10/09 PHP
php debug 安装技巧
2011/04/30 PHP
PHP 第二节 数据类型之数值型
2012/04/28 PHP
Zend studio文件注释模板设置方法
2013/09/29 PHP
php与flash as3 socket通信传送文件实现代码
2014/08/16 PHP
thinkphp3.2嵌入百度编辑器ueditor的实例代码
2017/07/13 PHP
js动态给table添加/删除tr的方法
2013/08/02 Javascript
js实现连续英文字符自动换行兼容ie6 ie7和firefox
2013/09/06 Javascript
js中window.open()的所有参数详细解析
2014/01/09 Javascript
JavaScript中的索引数组、关联数组和静态数组、动态数组讲解
2014/11/08 Javascript
使用JavaScript链式编程实现模拟Jquery函数
2014/12/21 Javascript
jQuery中queue()方法用法实例
2014/12/29 Javascript
JS实现超过长度限制后自动跳转下一款文本框的方法
2015/02/23 Javascript
js实现的早期滑动门菜单效果代码
2015/08/27 Javascript
JavaScript实现的多个图片广告交替显示效果代码
2015/09/04 Javascript
浅谈Javascript中Object与Function对象
2015/09/26 Javascript
CSS中position属性之fixed实现div居中
2015/12/14 Javascript
详解Javacript和AngularJS中的Promises
2016/02/09 Javascript
JavaScript类型系统之布尔Boolean类型详解
2016/06/26 Javascript
jquery对所有input type=text的控件赋值实现方法
2016/12/02 Javascript
浅谈js函数三种定义方式 & 四种调用方式 & 调用顺序
2017/02/19 Javascript
angular-ngSanitize模块-$sanitize服务详解
2017/06/13 Javascript
Vue axios设置访问基础路径方法
2018/09/19 Javascript
vue组件实践之可搜索下拉框功能
2018/11/25 Javascript
LayUI switch 开关监听 获取属性值、更改状态的方法
2019/09/21 Javascript
初步探究Python程序的执行原理
2015/04/11 Python
Windows安装Python、pip、easy_install的方法
2017/03/05 Python
Python中作用域的深入讲解
2018/12/10 Python
python操作小程序云数据库实现简单的增删改查功能
2019/06/06 Python
Flask框架学习笔记之表单基础介绍与表单提交方式
2019/08/12 Python
利用python-docx模块写批量生日邀请函
2019/08/26 Python
浅谈keras中的keras.utils.to_categorical用法
2020/07/02 Python
美国网上书店:Barnes & Noble
2018/08/15 全球购物
YSL圣罗兰美妆英国官网:Yves Saint Laurent Beauty UK
2019/08/03 全球购物
股份转让协议书
2014/04/12 职场文书
Redis之RedisTemplate配置方式(序列和反序列化)
2022/03/13 Redis