在使用知乎,微博的时候,我们经常可以看到自己上传的图片被加上了文字水印,在实际的应用开发过程中,很多客户端都需要开发者自己编写 Canvs 绘制图形水印的方法,今天我想在这里介绍一个轻量级的开源 Android 图片水印框架来避免开发过程中编写复杂的绘图代码:AndroidWM,并且剖析它的实现过程和特色用法。

水印

这个框架最大程度上简化了图片水印绘制的问题,暴露了灵活的接口给用户使用。在绘制水印的时候,只需要创建一个水印对象,一个水印创建者对象,然后把定制的水印对象传给水印创建者即可。

实现水印第一步:引用类库 androidWM

如果你使用 Android Studio 进行项目的开发,只需要在应用 app 的 build.gradle 里面添加上这么一行代码:

dependencies {

...

implementation 'com.huangyz0918:androidwm:0.2.3'

...

}

然后点击同步 gradle,让其自动下载并且安装好依赖即可。

实现水印第二步:创建一个水印,完工!

androidWM 给我们提供了四种不同的水印:

图形水印

文字水印

隐形图形水印

隐形文字水印

我们可以创建不同的水印对象来实现对水印风格的定制化,比如我想创建一个文字水印,我就实例化一个WatermarkText,并且设置它的属性:

WatermarkText watermarkText = new WatermarkText(“Hello World”)

.setPositionX(0.5) // 横坐标

.setPositionY(0.5) // 纵坐标

.setTextAlpha(100) // 透明度

.setTextColor(Color.WHITE) // 文字水印文字颜色

.setTextFont(R.font.champagne) // 字体

.setTextShadow(0.1f, 5, 5, Color.BLUE); // 字体的阴影

这样我就拿到了一个文字水印 watermarkText ,接下来,我还需要一个画师帮助我把水印画到我想要的背景底图上面,于是我们需要实例化一个WatermarkBuilder:

WatermarkBuilder.create(this, backgroundBitmap) // 加载背景底图

.loadWatermarkText(watermarkText) // 加载水印对象

.getWatermark() // 绘制带有水印的图片

.setToImageView(backgroundView); // 设置结果到 ImageView 里

这里一气呵成,首先传入一个上下文 context,然后传入一张你想要绘制的背景底图,这个背景图片可以来自于一个 ImageView, 也可以来自于系统的资源(如: R.drawable.image),你要是想直接传入一个 Bitmap 也是可以的。最后,在调用完方法 .getWatermark() 以后,androidWM 可以帮助你直接将带有水印的图片设置到一个ImageView里面,或者使用方法 .getOutputImage() 获得输出的 Bitmap。

水印创建好啦!

同理,你也可以通过实例化一个 WatermarkImage 来创建一个图像水印:

WatermarkImage watermarkImage = new WatermarkImage(watermarkBitmap)

.setImageAlpha(80)

.setPositionX(0.5)

.setPositionY(0.5)

.setRotation(15)

.setSize(0.3);

WatermarkBuilder

.create(this, backgroundBitmap)

.loadWatermarkImage(watermarkImage)

.getWatermark()

.setToImageView(backgroundView);

Boom ! 画出来的水印长这样:

图片水印!小眼睛!

创建隐形水印

隐形水印是框架 androidWM 的一个特色,它支持两种不同方式的隐形水印:

LSB 空域隐形水印

频域水印

创建隐形水印的话,设置水印的位置和大小颜色就没有意义了,水印将被编码到肉眼不可见的空间,只有使用框架的某些方法才能够成功地检测出来。

创建一个隐形的水印也是很简单的,我们同样可以通过 WatermarkBuilder 来绘制一个隐形的文字或者是图形水印:

WatermarkBuilder

.create(this, backgroundBitmap)

.loadWatermarkImage(watermarkBitmap)

.setInvisibleWMListener(true, new BuildFinishListener() {

@Override

public void onSuccess(Bitmap object) {

if (object != null) {

// do something...

}

}

@Override

public void onFailure(String message) {

// do something...

}

});

在方法 .setInvisibleWMListener() 中第一个参数是用于选择水印模式的参数:

true 使用空域 LSB 方法绘制隐形水印

false 使用频域隐形水印

同样,对于隐形水印的检测,我们可以初始化一个水印检测器 WatermarkDetector :

WatermarkDetector

.create(inputBitmap, true)

.detect(false, new DetectFinishListener() {

@Override

public void onSuccess(DetectionReturnValue returnValue) {

Bitmap watermarkImage = returnValue.getWatermarkBitmap();

String watermarkString = returnValue.getWatermarkString();

}

@Override

public void onFailure(String message) {

// do something...

}

});

在函数创建的时候,也需要选择一种检测模式,如果是 LSB 空域水印的检测,在第二个布尔参数的位置传进 true,反正是频域隐形水印的话就传 false。在检测方法 detect() 的第一个参数也是类似,如果需要检测文字类的水印传入 true,图片类的水印传入 false。

添加图片作为隐形水印

LSB 实现隐形水印的原理

讲完了框架的使用,我们来说一下关于 androidWM 实现图片隐形水印的原理,首先要说 LSB 空域水印。LSB 的全称是 Least Significant Bits,即通过图形中最不重要的一些信息位来储存我们隐藏信息(水印)。LSB 方法是最简单的嵌入水印的方法,事实上,任何一幅图片都具备一定的容噪性,这表现在像素数据的最低有效位 (Least Significant Bit,LSB) 对人眼的视觉影响很小,秘密信息就隐藏在图像每一个像素的最低位或次低位,实现其不可见性。

添加文字作为图片水印

为了实现我们的隐形水印,androidWM 将一幅图片的所有像素提取出来,其中每个像素都可以分解为 ARGB 四位信息(分别是 alpha, red, green, blue),作为标准的 ARGB 编码方式,每一位都由一个从 0 到 255 的整形数字表示,其中作为人眼来说,最后一位色阶的细小变化是根本不会被观察到的,我们将水印的文字(或是图片)信息编码为一串二进制的字符,将每个 ARGB 的值的最后一位清零,用二进制字符替换,达到了利用最后一位色阶来储存隐藏的信息的作用。

LSB 编码方式

在实际的工程中,我们将水印信息编码成二进制以后,加上了非二进制的前后缀用于识别程序检测,同时,为了让整张图片都被水印给覆盖,我们的算法将水印信息循环地铺设在背景图片中,只要图片之中含有一个有效的水印信息,就能够成功地检测到。

对于 LSB 空域数字水印来说,其有如下优点:

支持的水印信息量大

对原图影响小

算法简单

但是其也有不可忽视地巨大缺点:

在空间域上绘制数字水印,水印会随着图片变化而破坏

稳定性差,不能抵抗图像的裁剪、缩放和 jpg 压缩

隐形数字水印_Android 实现图片水印与隐形数字水印相关推荐

  1. 隐形数字水印_轻量级安卓水印框架,支持隐形数字水印 AndroidWM

    AndroidWM 一个轻量级的 Android 图片水印框架,支持隐形水印和加密水印. English version 下载与安装 Gradle: implementation 'com.huang ...

  2. 使用图像处理技术去除图片水印

    电子科技大学 格拉斯哥学院 2017级吴子健2017200604029 前言 在各类信息爆炸式增长的今天,大量图片形式的信息被上传到因特网上.为了防止图片版权被窃取,大量图片制造者使用水印来确保图片版 ...

  3. 批量图片水印工具 TSR WatermarkImage ——自定义水印批量操作

    SR WatermarkImage 是一款好用且简单的添加数字水印到图像的水印添加工具,透明度支持自定义.通过TSR Watermark Image,你可以使用文字或其他作为水印的图片创建水印来源,并 ...

  4. 批量图片水印工具 TSR WatermarkImage附注册码与中文补丁

    TSR WatermarkImage v3.6.0.3 是一款好用且简单的添加数字水印到图像的水印添加工具,透明度支持自定义.通过TSR Watermark Image,你可以使用文字或其他作为水印的 ...

  5. ffmpeg指定位置添加文字图片水印

    FFmpeg命令详解_Android&Java&C-CSDN博客 ​​​​​​利用ffmpeg实现添加图片水印和文字水印,添加多个水印.代码和命令实现及中文水印乱码_浪漫老狼的博客-C ...

  6. 用java实现给图片增加图片水印或者文字水印(也支持视频图像帧添加水印)

    javaCV图像处理系列: javaCV图像处理之1:实时视频添加文字水印并截取视频图像保存成图片,实现文字水印的字体.位置.大小.粗度.翻转.平滑等操作 javaCV图像处理之2:实时视频添加图片水 ...

  7. win2d 图片水印

    win2d 图片水印 本文告诉大家如何使用 win2d 给图片加上水印. 安装 首先需要使用 Nuget 安装 win2d ,安装参见win10 uwp win2d 如果没有更新 dot net co ...

  8. php分析图片水印,PHP开发的文字水印,缩略图,图片水印实现类与用法示例

    本文实例讲述了PHP开发的文字水印,缩略图,图片水印实现类与用法.分享给大家供大家参考,具体如下: 1.实现类ImageToTest.class.php参考代码 class ImageToTest { ...

  9. CSDN博文中完美地去掉图片水印、调整图片位置和大小

    写在这里的初衷,一是备忘,二是希望得到高人指点,三是希望能遇到志同道合的朋友. 写博客的时候,大多数人会有这种感觉:图片上传会有水印,位置默认靠左,有时候嫌直接上传比较大,不太美观,特此查找了解决办法 ...

最新文章

  1. pandas使用dropna函数计算返回dataframe中不包含缺失值的行索引列表list(index of rows without missing values in dataframe)
  2. vue音乐笔记_Vue音乐项目笔记(二)
  3. 7-4 最短工期 (25 分)
  4. uiw 1.2.17 发布,基于 React 16 的组件库
  5. Android - 返回上一个界面finish()方法
  6. BZOJ1787 Meet紧急集合
  7. Java中四大代码块的执行顺序(附code)
  8. 干货|java缓存技术详解
  9. 大牛直播SDK: 如何实现简单粗暴靠谱的直播抓娃娃方案
  10. Java DataStore 封装代码
  11. Unity 抗锯齿方案梳理
  12. win7家庭版升级win7旗舰版
  13. win7上的截图小工具
  14. 深入理解Java虚拟机——Parallel Scavenge收集器
  15. 牛客多校第九场K-The Flee Plan of Groundhog(树形DP)
  16. wiki维基百科各种语料数据下载
  17. 网页模板设计中5种常见的设计版式类型介绍
  18. 控件获取图像可从几方面取得?_基于图像特征与布局刻画的移动测试脚本跨平台录制回放...
  19. 音乐播放器的设计与实现 功能要求:设计一款基于HTML5音频技术的音乐播放器,要求实现音乐的播放、暂停、音量大小调节、上一首和下一首切换,运行效果如图所示
  20. 软件工程一位大三学生成功上大学的案例

热门文章

  1. BurpSuite配置抓取HTTPS数据包
  2. 敏捷开发产品管理系列之六:Product Servant
  3. BPF和Go:在Linux中内省的现代方式[译]
  4. 测试你的身份证号码最后一位,校验码的生成方式
  5. python下载b站视频_爬虫可以当是一个批量下载工具!用Python批量下载B站视频
  6. colormap保存 matlab_matlab的colormap的保存
  7. CSS 选择器 CSS3选择器
  8. lt;#37;= %、lt;#37; %、lt;#37;@ %、lt;#37;:%和lt;#37;# %的区别
  9. CSS3的:nth选择器
  10. eversync safari_EverSync app下载-浏览器书签收藏夹同步备份EverSync下载v1.11.1 安卓版-西西软件下载...