Android 给图片加上水印的示例代码(支持logo+文字)
时间:2022-07-27
本文章向大家介绍Android 给图片加上水印的示例代码(支持logo+文字),主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
本文介绍了Android 给图片加上水印的示例代码(支持logo+文字),分享给大家,具体如下:
现在我们想要往图片上打上水印,该水印应符合这样的需求的:
- 支持logo+文字;
- 文字信息支持多行展示;
- 用户可以选择水印在图片上的生成位置(左上、右上、右下和左下)。
粗略的结构图低配版大概就长这样…
水印结构图.png
现在提供这样的一种思路去实现这一个需求,我们可以通过自定义一个view,view的布局中包含logo、公司名称和相关信息,这个view就是我们要打上图片的水印。
这样的一个view其实是一个自定义组合布局,关于如何实现组合布局的自定义view,可以参考这篇文章:Android 自定义View实践之组合控件实现布局的复用
有了水印的view之后,我们就可以利用以下这个方法,得到水印的view的Bitmap。
/**
* 将一个view转换为Bitmap
* @param view
* @return
*/
public static Bitmap convertViewToBitmap(View view){
view.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
view.buildDrawingCache();
Bitmap bitmap = view.getDrawingCache();
return bitmap;
}
得到水印的view的Bitmap之后,处理一下尺寸,保持水印的尺寸在合理范围内。
//根据原图处理要生成的水印的宽高
float width = sourBitmap.getWidth();
float height = sourBitmap.getHeight();
float be = width / height;
if ((float) 16 / 9 = be && be = (float) 4 / 3) {
//在图片比例区间内16;9~4:3内,将生成的水印bitmap设置为原图宽高各自的1/5
waterBitmap = WaterMaskUtil.zoomBitmap(waterBitmap, (int) width / 5, (int) height / 5);
} else if (be (float) 16 / 9) {
//生成4:3的水印
waterBitmap = WaterMaskUtil.zoomBitmap(waterBitmap, (int) width / 5, (int) width*3 / 20);
} else if (be < (float) 4 / 3) {
//生成4:3的水印
waterBitmap = WaterMaskUtil.zoomBitmap(waterBitmap, (int) height*4 / 15, (int) height / 5);
}
然后将它按照要求绘制在原图上,提供生成左上、右上、右下和左下四个位置的水印各自的方法,关键代码如下:
/**
* 设置水印图片在左上角
* @param src
* @param watermark
* @param paddingLeft
* @param paddingTop
* @return
*/
public static Bitmap createWaterMaskLeftTop(
Context context, Bitmap src, Bitmap watermark,
int paddingLeft, int paddingTop) {
return createWaterMaskBitmap(src, watermark,
dp2px(context, paddingLeft), dp2px(context, paddingTop));
}
/**
* 设置水印图片在右下角
* @param src
* @param watermark
* @param paddingRight
* @param paddingBottom
* @return
*/
public static Bitmap createWaterMaskRightBottom(
Context context, Bitmap src, Bitmap watermark,
int paddingRight, int paddingBottom) {
return createWaterMaskBitmap(src, watermark,
src.getWidth() - watermark.getWidth() - dp2px(context, paddingRight),
src.getHeight() - watermark.getHeight() - dp2px(context, paddingBottom));
}
/**
* 设置水印图片到右上角
* @param src
* @param watermark
* @param paddingRight
* @param paddingTop
* @return
*/
public static Bitmap createWaterMaskRightTop(
Context context, Bitmap src, Bitmap watermark,
int paddingRight, int paddingTop) {
return createWaterMaskBitmap( src, watermark,
src.getWidth() - watermark.getWidth() - dp2px(context, paddingRight),
dp2px(context, paddingTop));
}
/**
* 设置水印图片到左下角
* @param src
* @param watermark
* @param paddingLeft
* @param paddingBottom
* @return
*/
public static Bitmap createWaterMaskLeftBottom(
Context context, Bitmap src, Bitmap watermark,
int paddingLeft, int paddingBottom) {
return createWaterMaskBitmap(src, watermark, dp2px(context, paddingLeft),
src.getHeight() - watermark.getHeight() - dp2px(context, paddingBottom));
}
/**
* 绘制水印图片
* @param src 原图
* @param watermark 水印
* @param paddingLeft
* @param paddingTop
* @return
*/
private static Bitmap createWaterMaskBitmap(Bitmap src, Bitmap watermark,
int paddingLeft, int paddingTop) {
if (src == null) {
return null;
}
int width = src.getWidth();
int height = src.getHeight();
//创建一个bitmap
Bitmap newb = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);// 创建一个新的和SRC长度宽度一样的位图
//将该图片作为画布
Canvas canvas = new Canvas(newb);
//在画布 0,0坐标上开始绘制原始图片
canvas.drawBitmap(src, 0, 0, null);
//在画布上绘制水印图片
canvas.drawBitmap(watermark, paddingLeft, paddingTop, null);
// 保存
canvas.save(Canvas.ALL_SAVE_FLAG);
// 存储
canvas.restore();
return newb;
}
绘制后的效果应该是这样的,欢迎拍砖~
给图片加上水印.png
附上源代码:github传送门
以上就是本文的全部内容,希望对大家的学习有所帮助。
- MySQL和Oracle中的隐式转换(r6笔记第45天)
- R语言的数据导入与导出(write.table,CAT)
- gqlplus的简单使用(r6笔记第43天)
- Java基础-21(01)总结字符流,IO流编码问题,实用案例必做一遍
- zabbix中配置dg的监控(r6笔记第62天)
- Apache ActiveMQ 远程代码执行漏洞 (CVE-2016-3088)分析
- mysql5.5与mysq 5.6中禁用innodb引擎的方法
- 缓慢的update语句性能分析(r6笔记第61天)
- 一个dg警告发现的硬件问题 (r6笔记第60天)
- mysql几种存储引擎介绍
- Java基础-21(02)总结字符流,IO流编码问题,实用案例必做一遍
- DeDeCMS v5.7 密码修改漏洞分析
- Java基础-20(01)总结,递归,IO流
- 一个Oracle bug的手工修复(r6笔记第59天)
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- SpringCloud+MyBatis分页处理(前后端分离)
- 手把手教你搭建SpringCloud项目
- SpringCloud的@Value注解及GitLab配置使用
- 使用 cdk8s 与 Argo CD 进行 GitOps 实践
- 设计模式 | 模版方法
- Python 函数3000字使用总结
- 3D摇杆控制器一种简单实现!Cocos Creator 3D!
- 数据结构 | TencentOS-tiny中队列、环形队列、优先级队列的实现及使用
- RTOS内功修炼记(六)—— 任务间通信为什么不用全局变量?
- 程序员必备基础:加签验签
- 【Rust日报】2020-07-16 j4rs,一个在 Rust 中调用 Java 代码的 Crate
- Vue.js 3 正式进入 RC 阶段
- FeignClient注解及参数问题---SpringCloud微服务
- Rust FFI 编程 - Rust导出共享库01
- 【每周一库】 see - An HTTP server for hosting static files