Android Canvas画布saveLayer与对应restoreToCount,Kotlin

Android Canvas画布saveLayer与对应restoreToCount,Kotlin

Kotlin 复制代码
    private fun mydraw() {
        val originBmp = BitmapFactory.decodeResource(resources, R.mipmap.pic).copy(Bitmap.Config.ARGB_8888, true)

        val newBmp = Bitmap.createBitmap(originBmp.width, originBmp.height, Bitmap.Config.ARGB_8888)
        val canvas = Canvas(newBmp)

        //把原图绘制在画布Canvas
        canvas.drawBitmap(originBmp, 0f, 0f, null)
        iv?.setImageURI(Uri.fromFile(saveBitmapToFile(newBmp)))

        val paint = Paint(Paint.ANTI_ALIAS_FLAG)
        paint.color = Color.RED
        paint.textSize = 40f
        paint.style = Paint.Style.STROKE
        paint.strokeWidth = 2f
        paint.textAlign = Paint.Align.LEFT


        //新图层,绿色背景,红色圆圈。
        val layer1 = canvas.saveLayer(0f, 0f, canvas.width.toFloat(), (canvas.height.toFloat() * 0.9).toFloat(), null)
        canvas.drawColor(Color.GREEN)
        canvas.drawCircle((canvas.width / 2).toFloat(), (canvas.height / 2).toFloat(), 50f, paint)
        canvas.restoreToCount(layer1)
        iv1?.setImageURI(Uri.fromFile(saveBitmapToFile(newBmp)))

        //新图层,灰色背景,直线。
        val layer2 = canvas.saveLayer(0f, 0f, canvas.width.toFloat(), (canvas.height.toFloat() * 0.8).toFloat(), null)
        canvas.drawColor(Color.GRAY)
        canvas.drawLine(
            canvas.width.toFloat() / 2,
            canvas.height.toFloat() / 2,
            canvas.width.toFloat(),
            canvas.height.toFloat(),
            paint
        )
        canvas.restoreToCount(layer2)
        iv2?.setImageURI(Uri.fromFile(saveBitmapToFile(newBmp)))

        //新图层,绿色背景,文字fly
        val layer3 = canvas.saveLayer(0f, 0f, canvas.width.toFloat(), (canvas.height.toFloat() * 0.5).toFloat(), null)
        canvas.drawColor(Color.BLUE)
        val x = 50f
        val y = 150f
        canvas.drawText("fly", x, y, paint)
        canvas.restoreToCount(layer3)
        iv3?.setImageURI(Uri.fromFile(saveBitmapToFile(newBmp)))

        /**
         * 如果不事先把bitmap通过文件形式存放好,再通过setImageURI设置到ImageView,那么就像
         * iv4?.setImageBitmap(newBmp),设置的newBmp是最终的绘图结果,saveLayer与restoreToCount操作的是在内存的newBmp,
         * 即便是ivx?.setImageURI后,newBmp内存数据变化,最终都是iv4里面的显示。为了细致观察这种区别,才先保存成不变的文件,再读文件加载出来观察。
         *
         * 注意,因为restoreToCount了,图层叠加到原图上,所以显示的结果是最后面的叠加到最前面的,把最前面的遮住了。
         * 如果不restoreToCount,则不会叠加,因为saveLayer创建了一个透明图层,是在原图之上的绘制。
         */


        iv4?.setImageBitmap(newBmp)
    }
    
    private fun saveBitmapToFile(bm: Bitmap): File? {
        var saveFile: File? = null
        val savePath =
            Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).toString()
        if (!Files.exists(Paths.get(savePath))) {
            Log.d("保存文件", "${savePath}不存在!")
        } else {
            saveFile = File(savePath, System.currentTimeMillis().toString() + ".jpeg")
            try {
                val saveImgOut = FileOutputStream(saveFile)
                //压缩
                bm.compress(Bitmap.CompressFormat.JPEG, 90, saveImgOut)
                saveImgOut.flush()
                saveImgOut.close()
                Log.d("保存文件", "Bitmap保存至 ${saveFile.absoluteFile.toPath()}")
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }

        return saveFile
    }

如果把

Kotlin 复制代码
canvas.restoreToCount()

全部注释掉,则为

Android Canvas状态save与restore,Kotlin-CSDN博客文章浏览阅读218次,点赞3次,收藏3次。文章浏览阅读9.6k次。文章浏览阅读1.8k次。/*Java代码 将Drawable转化为Bitmap */ Bitmap drawableToBitmap(Drawable drawable) { int width = drawable.getIntrinsicWidth();Android Material Design :LinearLayoutCompat添加分割线divider_linearlayout 分割线-CSDN博客。https://blog.csdn.net/zhangphil/article/details/135113616

相关推荐
日光明媚1 小时前
一步生成视频!One-Forcing:DMD + 零成本 GAN,训练 200 步超越多步 SOTA
android·开发语言·kotlin
帅次2 小时前
Android 17 开发者实战:核心更新与应用场景落地指南
android·java·ios·android studio·iphone·android jetpack·webview
大鹏说大话2 小时前
SQL 排序与分组实战:解决“分组后取最新数据“
android·java·数据库
plainGeekDev3 小时前
Android运行时面试题:ART和JVM的区别都搞不清,别写精通了
jvm·面试·kotlin
搜狐技术产品小编20235 小时前
破局与重构:纯端侧 Android 自动化引擎的尝试与未来推演
android·运维·重构·自动化
码云骑士6 小时前
Android SystemServer启动过程
android·systemserver
weiggle7 小时前
第三篇:可组合函数(Composable)——Compose 的基石
android·前端
独隅7 小时前
Android Studio 接入多种不同 AI 大模型进行开发的全面详细指南(Android Studio+AI)
android·人工智能·android studio
夜微凉48 小时前
三、MySQL
android·数据库·mysql
我命由我123458 小时前
Android 开发问题:项目同时引入了两个包含相同类文件的库(AndroidX 库、旧版本支持库),导致了重复类错误
android·java·java-ee·android studio·android-studio·androidx·android runtime