Android多张图片融合组合成一张新图片

在Android开发中,图像融合是一项常见且重要的技术,它能够将多张图像按照一定的规则组合成一张新的图像,广泛应用于图像处理、摄影后期、游戏开发等领域。普通项目中最常见的有二维码中间叠加logo、涂鸦、水印、广告图掏空部分显示出底下的内容等等。

图像融合基本概念:

图像融合是指将两个或多个图像按照一定的算法进行合成,生成一幅新的图像。在Android平台上,图像融合通常涉及到像素级别的操作,即根据一定的规则计算每个像素点的颜色值,从而得到融合后的图像。图像融合可以增强图像的视觉效果,提高图像的信息量,为用户提供更加丰富的视觉体验。

图像融合基本步骤:

1.加载所有待融合的图片资源均转成位图Bitmap

复制代码
 Bitmap bitmap1 = BitmapFactory.decodeResource(getResources(), R.drawable.image1);
 Bitmap bitmap2 = BitmapFactory.decodeResource(getResources(), R.drawable.image2);

2.创建一个新的位图Bitmap对象作为画布Canvas,设置融合模式,并在画布上根据需求规则绘制各个需融合的位图

复制代码
 Bitmap resultBitmap = Bitmap.createBitmap(bitmap1.getWidth(), bitmap1.getHeight(), bitmap1.getConfig());
 Canvas canvas = new Canvas(resultBitmap);

 Paint paint = new Paint();
 paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SCREEN));
 // 或者使用其他融合模式,如 PorterDuff.Mode.MULTIPLY

 canvas.drawBitmap(bitmap1, 0, 0, null);
 canvas.drawBitmap(bitmap2, 0, 0, paint); // 使用设置的融合模式绘制第二张图片

3.将融合后的位图进行显示或者保存到本地

复制代码
//显示
imageView.setImageBitmap(resultBitmap);
//保存到本地
FileOutputStream out = new FileOutputStream(fusionFile);
            // 压缩Bitmap到PNG格式并写入文件
            resultBitmap.compress(Bitmap.CompressFormat.PNG, 60, out);
            // 关闭输出流
            out.flush();
            out.close();

关于三种融合模式(Xfermode):

实践需求:

有一张大的半透底图bmp_bg和一张小的半透上层图bmp_top,现需要用小图覆盖大图的左上角部分,从而实现替换一些由第三方提供的不可控内容,由于都是半透图,直接叠加的话无法实现完全遮挡,所以需要将被覆盖的底图部分掏空成全透明的。以下是具体实现逻辑:

复制代码
try {
            Bitmap bmp_bg = BitmapFactory.decodeFile(bgFile.getAbsolutePath());
            Bitmap bmp_top = BitmapFactory.decodeFile(topFile.getAbsolutePath());
           //创建新位图做为画布
            Bitmap resultBitmap = Bitmap.createBitmap(bmp_bg.getWidth(), bmp_bg.getHeight(), bmp_bg.getConfig());
            Canvas canvas = new Canvas(resultBitmap);
            canvas.drawBitmap(bmp_bg, 0, 0, null);
            Paint transparentPaint = new Paint();
            //根据小图大小,将底图左上角部分清空
            transparentPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
            Rect transparentArea = new Rect(0, 0,bmp_top.getWidth(), bmp_top.getHeight()); // x, y是区域左上角坐标,width和height是区域的宽和高
            canvas.drawRect(transparentArea, transparentPaint);
            //将小图进行叠加
            transparentPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SCREEN)); 
            canvas.drawBitmap(bmp_top, 0, 0, transparentPaint);
            Log.i("charge", "==fusion end time=" + System.currentTimeMillis());
            //加融合结果新图片保存到本地
            if (!fusionFile.exists())
                fusionFile.createNewFile();
            // 创建文件输出流
            FileOutputStream out = new FileOutputStream(fusionFile);
            // 压缩Bitmap到PNG格式并写入文件
            resultBitmap.compress(Bitmap.CompressFormat.PNG, 60, out);
            // 关闭输出流
            out.flush();
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
相关推荐
千里马学框架13 小时前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台13 小时前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone14 小时前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc14 小时前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo16 小时前
Kotlin 协程中的 Job 结构化并发与取消
android
sun00770016 小时前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼17 小时前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
AFinalStone18 小时前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen18 小时前
属性动画原理与高级动画实现
android·kotlin·canvas
AFinalStone18 小时前
Android7 SystemUI 源码解析(二)启动流程深度解析
android·systemui