Android双击图片放大移动图中双击点到ImageView区域中心,Kotlin

news2024/11/27 10:23:55

Android双击图片放大移动图中双击点到ImageView区域中心,Kotlin

 

初始化状态,ImageView里面只是显示一张fitcenter被缩放的原图,当手指在图片上双击后(记录双击点位置:mCurX,mCurY)画一个红色小圆圈标记双击位置,放大图片,然后把放大后的图的(原mCurX,mCurY)位置移动到区域中心点位置,用大的红色圆圈标记。

 

双击:

1cd62e11f6a6437aa3f86b8a1086eaa7.png

 

 

放大图片,并把原来图中的双击点移动到区域中心,用大红圆圈标记:

ff67026c212149eaa35b2ae83eaf0f69.png

 


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

    private val mCirclePaint = Paint()

    private var mSrcBmp: Bitmap? = null
    private var mScaleBmp: Bitmap? = null
    private var testIV: ImageView? = null

    //放大系数。
    private val mScaleFactor = 4f
    private var mGestureDetector: GestureDetector? = null
    private var mIsDoubleTap = false
    private var mCanDraw = false

    constructor(ctx: Context, attrs: AttributeSet) : super(ctx, attrs) {
        mSrcBmp = (drawable as BitmapDrawable).bitmap //mSrcBmp是原始图大小,没有缩放和拉伸的。

        mCirclePaint.style = Paint.Style.STROKE
        mCirclePaint.strokeWidth = 10f
        mCirclePaint.isAntiAlias = true
        mCirclePaint.color = Color.RED

        mGestureDetector = GestureDetector(ctx, object : GestureDetector.SimpleOnGestureListener() {
            override fun onDoubleTap(e: MotionEvent): Boolean {
                mIsDoubleTap = true
                return false
            }
        })
    }

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

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

        mGestureDetector?.onTouchEvent(event)

        mCanDraw = true

        invalidate()

        return true
    }

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

        if (mCanDraw) {
            canvas.drawCircle(mCurX, mCurY, 10f, mCirclePaint)
        }

        if (mIsDoubleTap) {
            myDraw(canvas)
        }
    }

    private fun myDraw(canvas: Canvas) {
        Thread.sleep(1000)

        if (mScaleBmp == null) {
            //创建一次,避免重复创建,提高速度。
            mScaleBmp = Bitmap.createScaledBitmap(
                mSrcBmp!!,
                (this.width * mScaleFactor + 1).toInt(), //注意这里的精度损失,会造成坐标偏移.
                (this.height * mScaleFactor + 1).toInt(),//注意这里的精度损失,会造成坐标偏移.
                true
            )
        }

        val cx = this.width / 2f
        val cy = this.height / 2f

        val matrix = Matrix()
        matrix.setScale(mScaleFactor, mScaleFactor)
        matrix.setTranslate(cx - mCurX * mScaleFactor, cy - mCurY * mScaleFactor)
        canvas.drawBitmap(mScaleBmp!!, matrix, null)

        //中心圆圈
        canvas.drawCircle(cx, cy, 40f, mCirclePaint)
    }
}

 

 

xml里面定义MyImageView,特别的属性设置:

        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:adjustViewBounds="true"
        android:scaleType="fitCenter"

 

 

 

 

 

Android Matrix绘制PaintDrawable设置BitmapShader,手指触点为圆心scale放大原图,Kotlin(二)-CSDN博客文章浏览阅读197次。遗留问题,手指在上图滑动过程中,当滑动到一定区域,下面的切图框中已无太有效的图可以“放大”,后续可以填充黑色,表示无效放大。所有的绘制轨迹线,都限定在了绿色的圆角矩形框中,超出区域不予绘制。基础上,限定下面切图的绘制区域,超出绿色区域的轨迹线不再绘制。https://blog.csdn.net/zhangphil/article/details/135601993

Android Matrix剪切clipPath缩放scale图片postTranslate圆形放大镜,Kotlin(1)-CSDN博客文章浏览阅读1.3k次,点赞19次,收藏17次。需要注意的,因为在xml布局里面特别设置了ImageView的高度为wrap_content,手指在屏幕触点的位置是放大镜里面放大图片后准确圆心位置,但是,如果ImageView设置成match_parent,则因为ImageView里面的Bitmap被缩放(此处Bitmap其实小于ImageView,被拉伸了),拉伸后的Bitmap水平方向坐标与ImageView一直重合,但竖直方向,Bitmap坐标与ImageView不一致,会造成一种现象,手指触点放大镜放大后,水平方向是正确的,但竖直方向有偏移量。https://blog.csdn.net/zhangphil/article/details/135172744

Android:GestureDetector.SimpleOnGestureListener,onFling,onScroll,velocityX,Y&distanceX,Y,kotlin_gesturedetector.simpleongesturelistener onscroll-CSDN博客文章浏览阅读184次。Android不用OnScrollListener采用GestureDetector结合OnTouchListener实现ListView下拉/上拉刷新通常Android的ListView的下拉/上拉刷新实现,使用OnScrollListener比较简单,比如如果要实现下拉见顶刷新,思路是在OnScrollListener判断当前ListView的滚动状态,如果滚动停止,则将此时Lis。_gesturedetector.simpleongesturelistener onscrollhttps://blog.csdn.net/zhangphil/article/details/130812011

 

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

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

相关文章

TensorRT模型优化部署 (八)--模型剪枝Pruning

系列文章目录 第一章 TensorRT优化部署(一)–TensorRT和ONNX基础 第二章 TensorRT优化部署(二)–剖析ONNX架构 第三章 TensorRT优化部署(三)–ONNX注册算子 第四章 TensorRT模型优化部署(四&am…

AxiosError: Request failed with status code 503

spring.application.name属性指定了应用程序的名称为ssm_serviceA。这个属性用于标识应用程序,可以在日志、监控和其他相关功能中使用。通常情况下,应用程序的名称是用来区分不同的应用程序或服务的。 通过配置spring.application.name,你可以…

LSTM学习笔记

上一篇文章中我们提到,CRNN模型中用于预测特征序列上下文的模块为双向LSTM模块,本篇中就来针对该模块的结构和实现做一些理解。 Bidirectional LSTM模块结构如下图所示: 在Pytorch中,已经集成了LSTM模块,定义如下&…

Sqoop故障排除指南:处理错误和问题

故障排除是每位数据工程师和分析师在使用Sqoop进行数据传输时都可能遇到的关键任务。Sqoop是一个功能强大的工具,但在实际使用中可能会出现各种错误和问题。本文将提供一个详尽的Sqoop故障排除指南,涵盖常见错误、问题和解决方法,并提供丰富的…

认识并使用Shiro技术

认识并使用Shiro 一、对Shiro的基本认知1、Shiro是什么?2、Shiro的核心组件是?2.1 Subject2.2 UsernamePasswordToken2.3 Realm(重点是:AuthorizingRealm用于授权、AuthenticatingRealm用于认证)2.4 SecurityManager2.…

NLP论文阅读记录 - 2021 | WOS 基于多头自注意力机制和指针网络的文本摘要

文章目录 前言0、论文摘要一、Introduction1.1目标问题1.2相关的尝试1.3本文贡献 二.问题定义和解决问题的假设问题定义解决问题的假设 三.本文方法3.1 总结为两阶段学习3.1.1 基础系统 3.2 重构文本摘要 四 实验效果4.1数据集4.2 对比模型4.3实施细节4.4评估指标4.5 实验结果4…

面试官:什么是泛型擦除、泛型上界、泛型下界、PECS原则?

尼恩说在前面 在40岁老架构师 尼恩的读者交流群(50)中,最近有小伙伴拿到了一线互联网企业如阿里、滴滴、极兔、有赞、希音、百度、网易、美团的面试资格,遇到很多很重要的面试题: 问题1:什么是PECS原则? 说说具体怎么…

回溯法:回溯法通用模版以及模版应用

从一个问题开始 给定两个整数 n 和 k,返回 1 ... n 中所有可能的 k 个数的组合。 示例: 输入: n 4, k 2 输出: [ [2,4], [3,4], [2,3], [1,2], [1,3], [1,4] ] 很容易想到 用两个for循环就可以解决。 如果n为100,k为50呢,那就50层for循…

文字的baseLine算法

使用canvas的drawText方法时候,除了要传入画笔和text还需要传入一个x坐标和y坐标。这边的x和y坐标是Baseline的坐标。 public void drawText(NonNull String text, float x, float y, NonNull Paint paint) {super.drawText(text, x, y, paint);} top:是 baseLine到…

微信小程序之WXML 模板语法之数据绑定、事件绑定、wx:if和列表渲染

学习的最大理由是想摆脱平庸,早一天就多一份人生的精彩;迟一天就多一天平庸的困扰。各位小伙伴,如果您: 想系统/深入学习某技术知识点… 一个人摸索学习很难坚持,想组团高效学习… 想写博客但无从下手,急需…

消息中间件之Kafka(二)

1.Kafka线上常见问题 1.1 为什么要对topic下数据进行分区存储? 1.commit log文件会受到所在机器的文件系统大小的限制,分区之后可以将不同的分区放在不同的机器上, 相当于对数据做了分布式存储,理论上一个topic可以处理任意数量的数据2.提…

OpenHarmony 应用开发入门 (二、应用程序包结构理解及Ability的跳转,与Android的对比)

在进行应用开发前,对程序的目录及包结构的理解是有必要的。如果之前有过android开发经验的,会发现OpenHarmony的应用开发也很简单,有很多概念是相似的。下面对比android分析总结下鸿蒙的应用程序包结构,以及鸿蒙对比android的诸多…

【报错】Arco新建工程时 Error: spawnSync pnpm.cmd ENOENT

文章目录 安装环境开始安装选择技术栈选择pro项目遇到的问题 安装步骤:https://arco.design/vue/docs/pro/start 安装环境 npm i -g arco-cli开始安装 arco init hello-arco-pro选择技术栈 ? 请选择你希望使用的技术栈React❯ Vue选择pro项目 ? 请选择一个分类业…

智谱AI发布新一代国产文本生成模型:GLM-4,“宣称”性能逼近GPT-4 (怎么又是GPT )

希望别又是一个只顾着跑分数不注重性能的东西。。。 智谱AI GLM-4介绍体验网址链接:智谱AI开放平台 更多消息:AI人工智能行业动态,aigc应用领域资讯 智谱AI是一家专注于人工智能技术研发和应用的公司,致力于打造全球领先的大模型…

2024年美赛数学建模思路 - 案例:感知机原理剖析及实现

文章目录 1 感知机的直观理解2 感知机的数学角度3 代码实现 4 建模资料 # 0 赛题思路 (赛题出来以后第一时间在CSDN分享) https://blog.csdn.net/dc_sinor?typeblog 1 感知机的直观理解 感知机应该属于机器学习算法中最简单的一种算法,其…

第二课:BERT

文章目录 第二课:BERT1、学习总结:为什么要学习BERT?预训练模型的发展历程BERT结构BERT 输入BERT EmbeddingBERT 模型构建BERT self-attention 层BERT self-attention 输出层BERT feed-forward 层BERT 最后的Add&NormBERT EncoderBERT 输…

深入剖析 Git 对象底层原理

一、引言 在我们日常使用 Git 时,通常的操作是: 在写完一段代码后,执行 git add命令,将这段代码添加到暂存区中然后再执行 git commit和 git push 命令,将 本地 Git 版本库中的提交同步到服务器中的版本库中 Git 在…

phpStorm 设置终端为git bash

环境: windows , PhpStorm 2022 为自己的终端配置git样式的使用, 默认终端样式 一、打开设置,选择git bin 二、重新打开终端 不加--login -i 的终端 加了--login -i 的终端 最重要的一点是什么,他可以像mac一样支持 ctrlv 复…

【学习记录】Ouster雷达运行fastlio提示 Failed to find match for field ‘ring‘ 的解决办法

本文仅用于个人记录。 在使用ouster雷达运行fastlio代码时,提示 Failed to find match for field ‘ring’ 但ouster雷达确实是发布了ring信息,可以从启动的rviz里面看到包括ring。 进一步检查,发现ouster对ring的定义是 uint_16t&#xf…

Redis: Redis介绍

文章目录 一、redis介绍二、通用的命令三、数据结构1、字符串类型(String)(1)介绍(2)常用命令(3)数据结构 2、列表(List)(1)介绍&…