Android基于Matrix绘制PaintDrawable设置BitmapShader,以手指触点为中心显示原图像圆图,Kotlin(2)

news2024/11/15 18:06:02

Android基于Matrix绘制PaintDrawable设置BitmapShader,以手指触点为中心显示原图像圆图,Kotlin(2)

 

在 https://zhangphil.blog.csdn.net/article/details/135374279 基础上,增加一个功能,当手指在上面的图片上滑动时候,显示滑动轨迹:

1deb0cfc742e4016acae8e98cc819466.png

 

import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapShader
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Matrix
import android.graphics.Paint
import android.graphics.Path
import android.graphics.Shader.TileMode
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.PaintDrawable
import android.os.Bundle
import android.util.AttributeSet
import android.util.Log
import android.view.MotionEvent
import android.widget.ImageView
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.AppCompatImageView


class MainActivity : AppCompatActivity() {
    private var iv: MyImageView? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        iv = findViewById(R.id.iv)

        val r = findViewById<ImageView>(R.id.result)
        iv?.setTestImageView(r)
    }
}

class MyImageView : AppCompatImageView {
    private var mCurX = 0
    private var mCurY = 0

    private val mPath = Path()
    private val mPathPaint = Paint()

    private var mNewBmp: Bitmap? = null
    private var mSrcBmp: Bitmap? = null
    private var mIsDraw = false
    private val mRadius = 300f

    private var mDrawable: PaintDrawable? = null

    private var testIV: ImageView? = null

    constructor(ctx: Context, attrs: AttributeSet) : super(ctx, attrs) {
        mSrcBmp = (drawable as BitmapDrawable).bitmap

        mPathPaint.style = Paint.Style.STROKE
        mPathPaint.strokeWidth = 15f
        mPathPaint.isAntiAlias = true
        mPathPaint.color = Color.RED
    }

    fun setTestImageView(iv: ImageView?) {
        testIV = iv
    }

    override fun onTouchEvent(event: MotionEvent): Boolean {
        mCurX = event.x.toInt()
        mCurY = event.y.toInt()

        when (event.action) {
            MotionEvent.ACTION_DOWN -> {
                Log.d("fly", "开始绘制")

                mPath.moveTo(event.x, event.y)

                mIsDraw = true
            }

            MotionEvent.ACTION_MOVE -> {
                mPath.lineTo(event.x, event.y)
            }

            MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
                Log.d("fly", "不需绘制")
                mIsDraw = false

                //抬手后,清除手指轨迹。
                myClear()
            }
        }

        invalidate()

        return true
    }

    private fun myClear() {
        //清除历史轨迹。
        mPath.reset()
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)

        if (mIsDraw) {
            myDraw()

            canvas.drawPath(mPath, mPathPaint)
        }
    }

    private fun myDraw() {
        val shader = BitmapShader(Bitmap.createScaledBitmap(mSrcBmp!!, this.width, this.height, true), TileMode.DECAL, TileMode.DECAL)
        mDrawable = PaintDrawable(Color.DKGRAY)
        mDrawable!!.setCornerRadius(mRadius / 2) //圆角矩形,如果不除2即是圆形框图。
        mDrawable!!.paint.shader = shader
        mDrawable!!.setBounds(0, 0, (mRadius * 2).toInt(), (mRadius * 2).toInt())

        mNewBmp = Bitmap.createBitmap(this.width, this.height, Bitmap.Config.ARGB_8888)
        val c = Canvas(mNewBmp!!)
        c.drawColor(Color.LTGRAY) //画满底色。


        val matrix = Matrix()
        matrix.setTranslate(-mCurX + mRadius, -mCurY + mRadius)
        mDrawable!!.paint.shader.setLocalMatrix(matrix)

        mDrawable!!.draw(c)


        testIV?.setImageBitmap(mNewBmp)
    }
}

 

 

 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/darker_gray"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <com.pkg.MyImageView
        android:id="@+id/iv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:adjustViewBounds="true"
        android:background="@drawable/ic_launcher_background"
        android:scaleType="fitCenter"
        android:src="@mipmap/mypic" />

    <ImageView
        android:id="@+id/result"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:background="@drawable/ic_launcher_background"
        android:src="@drawable/ic_launcher_foreground" />

</LinearLayout>

 

 

 

https://zhangphil.blog.csdn.net/article/details/135374279https://zhangphil.blog.csdn.net/article/details/135374279

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1378018.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

以报时机器人为例详细介绍tracker_store和event_broker

报时机器人源码参考[1][2]&#xff0c;本文重点介绍当 tracker_store 类型为 SQL 时&#xff0c;events 表的表结构以及数据是如何生成的。以及当 event_broker 类型为 SQL 时&#xff0c;events 表的表结构以及数据是如何生成的。 一.报时机器人启动 [3] Rasa 对话系统启动方…

基于springboot+vue心理测试管理系统

摘要 基于Spring Boot 和 Vue 的心理测试管理系统是一个综合利用现代Web开发技术的应用程序。系统采用了Spring Boot作为后端框架&#xff0c;通过其简化的配置和强大的功能提供了稳健的服务器端支持。前端则使用Vue.js&#xff0c;一个灵活、高效的JavaScript框架&#xff0c;…

通义千问AI挑战赛赛后反思

个人理解&#xff1a; 初赛阶段主要聚焦在如何通过 SFT 提升基础模型的代码能力&#xff0c;需要选手基于最新开源的 Qwen 1.8 模型作为基础模型&#xff0c;上分的关键主要通过收集高质量的代码数据提升模型的在Python, JavaScript, Java, Go, C, Rust六种编程语言的代码生成…

档案数字化怎样快速整理资料

对于机构和组织来说&#xff0c;档案数字化是一个重要的信息管理和保护措施。要快速整理资料进行档案数字化&#xff0c;可以遵循以下步骤&#xff1a; 1. 准备工具和设备&#xff1a;确保有一台计算机、扫描仪和相关软件。 2. 分类和组织资料&#xff1a;先将资料分类&#xf…

c++最值查找

目录 min和max函数 min_element和max_element 例 nth_element函数 例 例题 题目描述 输入描述 输出描述 解 min和max函数 只能传入两个值或一个列表 时间复杂度为O(1),数组O(n)&#xff0c;n为元素个数 min_element和max_element min_element(st,ed)返回地址[st,…

数据结构学习之顺序栈应用的案例(有效的括号)

实例要求&#xff1a; 给定一个只包括 (&#xff0c;)&#xff0c;{&#xff0c;}&#xff0c;[&#xff0c;] 的字符串 s &#xff0c;判断字符串是否有效&#xff1b; 有效字符串需满足的条件&#xff1a; 1、左括号必须用相同类型的右括号闭合&#xff1b; 2、左括号必须…

服务端性能测试——性能测试工具JMeter-L1

第一遍没学懂&#xff0c;后续文章会更新~ 目录&#xff1a; 1.JMeter介绍与安装Meter简介JMeter安装2.JMeter的运行JMeter运行、界面功能简介3.使用代理服务器录制请求录制压测脚本&#xff08;一&#xff09;Web端脚本录制方法4.测试计划5.线程组6.控制器7.JMeter采样器/取…

Postman接口测试工具最全实用教程

一、postman简介 1、postman的特点 postman只做http协议的接口的测试&#xff0c;是一种最广泛REST接口测试客户端软件。postman支持http协议的所有请求方式&#xff0c;包括get、post、head、put、delete等。postman支持各种额外的头部字段的添加。postman除了可以模拟普通表…

chat-plus部署指南

目录 1.下载代码 2.启动 3.测试 1.下载代码 cd /optwget https://github.com/yangjian102621/chatgpt-plus/archive/refs/tags/v3.2.4.1.tar.gz 2.启动 cd /opt/chatgpt-plus-3.2.4.1/deploydocker-compose up -d 3.测试 管理员地址xxx:8080/admin 账号密码admin/admin1…

java流程控制-给个一件三连呗!✨✨✨✨✨

接下来我们来看流程控制方面的知识 文章目录 1.Scanner类的使用1.1 使用next()进行接收1.2 nextLine()1.3 hasNext()1.4 scanner.nextInt() 2.选择结构2.1 if...else....语句2.2 if....else if....else...语句2.3 switch() case...语句 3.循环结构3.1for 循环&#xff1a;3.2w…

ES索引原理

ES在检索时底层使用的就是倒排索引&#xff0c;正向索引是通过key找value&#xff0c;反向索引则是通过value找key。 索引会分为两个区域&#xff1a;索引区和元数据区。数据是这样存储在里面的&#xff1a; 简单理解就是&#xff1a;当要录入一条数据时&#xff0c;首先会将完…

Linux之Iptables简易应用

文档形成时期&#xff1a;2009-2024年 和iptables打交道有15年了&#xff0c;经过无数实践后&#xff0c;形成一个简易应用文档。 文档主题是简易应用&#xff0c;所以其原理不详述了。 因软件世界之复杂和个人能力之限&#xff0c;难免疏漏和错误&#xff0c;欢迎指正。 文章目…

伴随矩阵定义和计算

一、伴随矩阵定义 1&#xff09;代数余子式 代数余子式也很好理解&#xff0c;在余子式的基础上多了一个-1的次方而已。 2)余子式 余子式很好理解&#xff0c;就是除了这个元素&#xff0c;出去该行该列剩下的行列式的值。 求每个元素的代数余子式&#xff0c;按行求&#xf…

关于白盒测试,这些技巧你得游刃有余~

对于很多刚开始学习软件测试的小伙伴来说&#xff0c;如果能尽早将黑盒、白盒测试弄明白&#xff0c;掌握两种测试的结论和基本原理&#xff0c;将对自己后期的学习有较好的帮助。今天&#xff0c;我们就来聊聊黑盒、白盒测试的相关话题。 1、黑盒测试的方法和小结 最常见黑盒…

【C++】:C++中的STL序列式容器vector源码剖析

⛅️一 vector概述 vector的使用语法可以参考文章&#xff1a;​ 总的来说&#xff1a;vector是可变大小数组 特点&#xff1a; 支持快速随机访问。在尾部之外的位置插入或删除元素可能很慢 元素保存在连续的内存空间中&#xff0c;因此通过下标取值非常快 在容器中间位置添加…

SpringIOC之support模块GenericApplicationContext

博主介绍:✌全网粉丝5W+,全栈开发工程师,从事多年软件开发,在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战,博主也曾写过优秀论文,查重率极低,在这方面有丰富的经验✌ 博主作品:《Java项目案例》主要基于SpringBoot+MyBatis/MyBatis-plus+…

【Spring 篇】基于注解的Spring事务控制详解

嗨&#xff0c;亲爱的读者朋友们&#xff01;欢迎来到这篇关于基于注解的Spring事务控制的博客。如果你曾为事务处理而头痛&#xff0c;那么这里将为你揭开事务的神秘面纱。我们将一步步深入探讨Spring事务的世界&#xff0c;用简单易懂的语言、充满情感色彩的文字&#xff0c;…

fastadmin 框架如何移除图片上传后预览中的删除按钮

在FastAdmin中&#xff0c;当我们启用了图片上传预览时&#xff0c;在预览区域会自动生成预览图和删除按钮&#xff0c;如下图&#xff1a; 如果我们想上移除掉这里的删除按钮&#xff0c;则需要启用自定义预览模板的功能。 首先我们找到视图中我们的预览容器&#xff0c;比如…

C++内存管理机制(侯捷)笔记4(完结)

C内存管理机制&#xff08;侯捷&#xff09; 本文是学习笔记&#xff0c;仅供个人学习使用。如有侵权&#xff0c;请联系删除。 参考链接 Youtube: 侯捷-C内存管理机制 Github课程视频、PPT和源代码: https://github.com/ZachL1/Bilibili-plus 介绍 下面是第四讲和第五讲…

STM32F103RCT6开发板M3单片机教程07-TIMER1CH1输出 PWM做LED呼吸灯

概述 本教程使用是&#xff08;光明谷SUN_STM32mini开发板&#xff09; 免费开发板 在谷动谷力社区注册用户&#xff0c;打卡&#xff0c;发帖求助都可以获取积分&#xff0c;当然最主要是发原创应用文档奖励更多积分&#xff0e; (可用积分换取&#xff0c;真的不用钱&…