隐形数字水印_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,转载请注明出处:https://javaforall.cn/234660.html原文链接:https://javaforall.cn

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

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

(0)
blank

相关推荐

  • linux下手动释放内存

    linux下手动释放内存

  • js的api文档_响应式编程

    js的api文档_响应式编程Web3.jsAPI中文文档web3对象提供了所有方法。

  • mysql修改表名

    mysql修改表名ALTER TABLE table_nameRENAMETOnew_table_name

  • 2021年各行业NPS基准分数一览[通俗易懂]

    2021年各行业NPS基准分数一览[通俗易懂]每每谈及NPS,总会有客户问我们:NPS分数达到多少才算得上好?这个问题没有统一的标准答案。因为NPS分数没有绝对的高低之分,不同行业之间标准不一。比如,根据TemkinGroup——知名的体验研究机构于2018年的调查,快餐行业的NPS均分是26,而医疗保健的NPS均分是19。因此,企业要想判断自己的NPS分数是好是坏,最需要了解的是所处行业的整体NPS水平。为了能够帮助大家快速了解自己在行业内的NPS地位,我们特别整理了分别处于ToB和ToC领域共14个行业的最新NPS基准分..

  • flask框架菜鸟教程_flask框架是用来干什么的

    flask框架菜鸟教程_flask框架是用来干什么的文章目录前言Flask基础概念和安装Flask快速入门小应用Flask之模板的使用后续,待更新。。。。前言最近开始学习flask框架,本文用于flask框架的基础入门学习,版本使用的是py3.7,学习内容相对比较简单,后续再扩充高级知识。Flask基础概念和安装首先我们得清楚,flask具体是个什么东东?我们学了flask有啥用?这里给出维基百科的解释:Flask是一个使…

  • html空格代码_html中空格怎么表示

    html空格代码_html中空格怎么表示html中空格代码的写法一:&nbsp(不换行空格)html中空格代码的写法二:&ensp(半角空格)html中空格代码的写法三:&emsp(全角空格)html中空格代码的写法四:&thinsp(窄空格)html中空格代码的写法五:&zwnj(零宽不连字)说明:&zwnj是一个不打印字符,放在电子文本的两个字符之间,抑制本来会发生的连字,而是以这两个字符原本的字形来绘制。html中空格代码的写法六:&zwj(零宽连字)说明:&amp

发表回复

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

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