隐形数字水印_Android 实现图片水印与隐形数字水印

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

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全家桶1年46,售后保障稳定

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

隐形数字水印_Android 实现图片水印与隐形数字水印

水印

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

实现水印第一步:引用类库 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。

隐形数字水印_Android 实现图片水印与隐形数字水印

水印创建好啦!

同理,你也可以通过实例化一个 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 ! 画出来的水印长这样:

隐形数字水印_Android 实现图片水印与隐形数字水印

图片水印!小眼睛!

创建隐形水印

隐形水印是框架 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。

隐形数字水印_Android 实现图片水印与隐形数字水印

添加图片作为隐形水印

LSB 实现隐形水印的原理

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

隐形数字水印_Android 实现图片水印与隐形数字水印

添加文字作为图片水印

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

隐形数字水印_Android 实现图片水印与隐形数字水印

LSB 编码方式

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

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

支持的水印信息量大

对原图影响小

算法简单

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

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

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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:http://www.javaforall.cn/234660.html原文链接:http://www.javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • 我的世界服务器显示标指令,我的世界服务器指令|我的世界服务器指令大全「建议收藏」

    我的世界服务器显示标指令,我的世界服务器指令|我的世界服务器指令大全「建议收藏」一砖一瓦一世界,这里是uc129我的世界专区。做为有着极高自由度的3d沙盘游戏我的世界来说,带给玩家的不止是视觉上的享受,通过自己的努力打造属于自己的游戏王国,则是游戏的魅力所在。对于minecraft服务器管理员来说,熟练掌握我的世界服务器指令是至关重要的。如果辛辛苦苦建立好服务器却发现对我的世界服务器指令根本就不了解,这是何等的杯具。接下来uc129小编将给大家分享一些服务器指令方面的内容,我…

  • Mac虚拟机联网(vmware虚拟机怎么联网)

    下载VMwareFusion安装,下载centOS7镜像并安装虚拟机查看本机的vmnet1和vmnet8MAC系统下通过终端的ifconfig命令可以得知当前主机的vmnet1(192.168.118.1)和vmnet8(192.168.2.1) 仅主机模式下通过vmnet1使得主机和虚拟机可以通信 NAT模式下通过vmnet8使得主机和虚拟机可以通信Mac终端cd/Libr…

  • networkx之图遍历和图绘制

    networkx之图遍历和图绘制networkx之图遍历和图绘制文章目录networkx之图遍历和图绘制图数据读取后默认标签(labels)为索引,如何使用编号id?图数据读取后,如何得到节点集和边集?如何绘制多样的图?图数据读取后默认标签(labels)为索引,如何使用编号id?例如在读取football数据时,其labels都是节点的英文名称,这样在处理图数据时不是很方便,往往报错,我们通常习惯处理节点的编号从1开始,可以建立label-id的反向索引,如果处理图数据时只需要编号id,可以将labels属性设置为id,如果之后还

  • 各种硬件接口_sdio接口速率

    各种硬件接口_sdio接口速率  SDIO接口是在SD内存卡接口的基础上发展起来的接口,SDIO接口兼容以前的SD内存卡,并且可以连接SDIO接口的设备。参考SDIO1.0标准定义了两种类型的SDIO卡:  全速的SDIO卡,传输率可以超过100Mbps;  低速的SDIO卡,支援的时脉速率在0至400KHz之间。  SDIO协议是由SD卡的协议演化升级而来的,很多地方保留了SD卡的读写协议,同时SDIO协议又在SD卡协议之上添加了CMD52和CMD53命令。由于这个,SDIO和SD卡规范间的一个重要区别是增加了低速标准,低速

  • 考研数学二常用公式_考研数学写公式有分吗

    考研数学二常用公式_考研数学写公式有分吗面(体)积公式一元二次方程基础极坐标方程与直角坐标转换切线与法线方程因式分解公式阶乘与双阶乘函数的奇偶性排列组合等差数列等比数列常用数列前n项和不等式三角函数公式诱导公式平方关系两角和与差的三角函数积化和差公式和差化积公式倍角公式半角公式万能公式其他公式反三角函数恒等式极限相关公式数列极限递推式重要极限公式常用等价无穷小1^∞型导数相关公式导数定义微分定义连续,可导及可微关系一元函数多元函数导数四则运算复合函数求导反函数求导参数方程

  • mybatiscodehelperpro激活码【2021.10最新】

    (mybatiscodehelperpro激活码)2021最新分享一个能用的的激活码出来,希望能帮到需要激活的朋友。目前这个是能用的,但是用的人多了之后也会失效,会不定时更新的,大家持续关注此网站~IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.cn/100143.html…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号