隐形数字水印_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 压缩

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

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/234660.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 嵌入式工程师岗位要求_fae和研发哪个工资高

    嵌入式工程师岗位要求_fae和研发哪个工资高FAE,嵌入式行业苦涩的职位FAE,也叫现场技术支持工程师大学招聘季的时候,憨娃娃一个,一心想找个嵌入式的职位,幻想着成为IronMan,左焊电路,右敲代码,打造属于自己的一身铁皮,成为村里走出去最科技的那个仔。现在想来,着实可笑了些。佩剑尚未佩好,出门就掉巨坑。“你要去的部门是我们公司最核心的部门,我们公司的主营业务都在那边。”HR的自豪我现在竟然还记得。“看起来我还是蛮优秀的嘛。”…

    2025年7月15日
    3
  • 基于DNS解析的GSLB《CDN技术详解》

    基于DNS解析的GSLB《CDN技术详解》基于DNS解析的GSLB工作方式基于DNS解析的GSLB方案实际上就是把负载均衡设备部署在DNS系统中。在用户发出任何应用连接请求时,首先必须通过DNS系统来请求获得服务器的IP地址,基于DNS的GSLB正是在返回DNS解析结果的过程中进行智能决策,给用户返回一个最佳的服务器的IP地址。从用户的视角看,整个应用流程与没有GSLB参与时没有发生任何变化。DNS系统本身是具备简单负载分配能力的,这…

    2022年6月10日
    41
  • amos中路径p值_输出无向图的路径

    amos中路径p值_输出无向图的路径基于Amos路径分析的输出结果参数详解1Outputpathdiagram2AmosOutput2.1AnalysisSummary2.2NotesforGroup2.3VariableSummary2.4ParameterSummary2.5Assessmentofnormality2.6Observationfarthestfromthecentroid(Mahalanobisdistance)2.7SampleMoments2.8Notesfor

    2022年8月24日
    8
  • 解读Take-Two新财报:营收、利润增长均不及预期,游戏巨头如何迎来第二春?

    解读Take-Two新财报:营收、利润增长均不及预期,游戏巨头如何迎来第二春?5月14日,美国发行商Take-Two对外发布了2019财年第四季度的新财报。根据财报内容来看,Take-Two在营收、净利润等核心数据上保持了一定同比增速,但均没有超出市场期待。受财报发布后的影响,Take-Two的股价一度下跌超6%。回顾Take-Two前几个季度的财报来看,整体股价表现并不是很稳定,这也说明Take-Two的营收表现并没有让投资者很满意。随着全球游戏市场的竞争加剧,尤其是移…

    2022年6月6日
    58
  • idea激活码2021破解方法[通俗易懂]

    idea激活码2021破解方法,https://javaforall.net/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

    2022年3月14日
    235
  • latex中的括号怎么打_小括号和中括号的简便算法

    latex中的括号怎么打_小括号和中括号的简便算法https://blog.csdn.net/han____shuai/article/details/49679335功能语法显示不好看    (\frac{1}{2})好一点\left(\frac{1}{2}\right)您可以使用\left和\right来显示不同的括号:功能语法显示圆括号,小括号\left( \frac{a}{b}\right)方括号,中括号\left[ \frac…

    2022年10月11日
    5

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

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