Android Matrix剪切clipPath缩放scale图片postTranslate圆形放大镜,Kotlin(2)

Android Matrix剪切clipPath缩放scale图片postTranslate圆形放大镜,Kotlin(2)

在 Android Matrix剪切clipPath缩放scale图片postTranslate圆形放大镜,Kotlin(1) Android Matrix剪切clipPath缩放scale图片postTranslate圆形放大镜,Kotlin(1)-CSDN博客 基础上,改进,使得ImageView的scaleType为fitCenter高度match_parent后,顶部留出空白,也能准确的在手指触点显示放大镜:

import android.content.Context
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Matrix
import android.graphics.Paint
import android.graphics.Path
import android.graphics.RectF
import android.graphics.drawable.BitmapDrawable
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.AppCompatImageViewclass MainActivity : AppCompatActivity() {private var image: MyImage? = nulloverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)image = findViewById(R.id.image)}
}class MyImage : AppCompatImageView {private val TAG = "fly"private var mIsDraw = falseprivate var curX: Float = 0fprivate var curY: Float = 0fprivate var originBmp: Bitmap = (drawable as BitmapDrawable).bitmapconstructor(ctx: Context, attrs: AttributeSet) : super(ctx, attrs)override fun onTouchEvent(event: MotionEvent?): Boolean {when (event?.actionMasked) {MotionEvent.ACTION_DOWN -> {mIsDraw = truecurX = event.xcurY = event.yinvalidate()}MotionEvent.ACTION_MOVE -> {curX = event.xcurY = event.yinvalidate()}MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {mIsDraw = falseinvalidate()}}return true}override fun draw(canvas: Canvas) {super.draw(canvas)if (canDraw()) {myDraw(canvas)}}private fun canDraw(): Boolean {return mIsDraw}/*** Matrix放大矩阵,通过clipPath剪切一块圆形区域作为放大镜区域,然后直接在clipPath的区域上绘制放大后的图。*/private fun myDraw(canvas: Canvas) {Log.d(TAG, "ImageView w=${width} h=${height} Bitmap w=${originBmp.width} h=${originBmp.height}")val path = Path()val radius = 250fval factor = 4fval paint = Paint(Paint.ANTI_ALIAS_FLAG)paint.color = Color.REDpaint.style = Paint.Style.STROKEpaint.strokeWidth = 10fpath.addCircle(curX, curY, radius, Path.Direction.CW)canvas.drawPath(path, paint) //画红色的圆圈,圆心是手指在屏幕上的触点。canvas.clipPath(path) //剪切出来一片圆形区域。//特别注意,这里固定以手机屏幕的宽度为基准等比例放大Bitmap。val scaleW: Float = resources.displayMetrics.widthPixels.toFloat()val scaleH: Float = (originBmp.height.toFloat() / originBmp.width.toFloat()) * scaleWLog.d(TAG, "display w=${scaleW} h=${scaleH}")val matrix = Matrix()matrix.setScale(factor, factor)//canvas.concat(matrix)val rectF = getBitmapBound(this)val dx = (rectF.left - curX) * factor + curXval dy = (rectF.top - curY) * factor + curY//上下左右移动矩阵,使得放大后的矩阵处于圆圈的内容刚好是手指触点为中心的圆图。matrix.postTranslate(dx, dy)canvas.drawBitmap(Bitmap.createScaledBitmap(originBmp, scaleW.toInt(), scaleH.toInt(), true),matrix,paint)}private fun getBitmapBound(imageView: ImageView): RectF {val bounds = RectF()val drawable = imageView.drawableif (drawable != null) {imageView.imageMatrix.mapRect(bounds, RectF(drawable.bounds))}return bounds}
}

    <com.pkg.MyImageandroid:id="@+id/image"android:layout_width="match_parent"android:layout_height="match_parent"android:adjustViewBounds="true"android:scaleType="fitCenter"android:src="@mipmap/p2" />

ImageView由于高度在xml布局设置match_parent,撑满整个屏幕,但由于图像的Bitamp缩放为fitCenter没有充满整个ImageView。主要是计算ImageView里面Bitmap的RectF区域,然后顶部和坐标做一定偏移,对准手指触点位置。

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

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Apache Doris (六十): Doris - 物化视图

🏡 个人主页:IT贫道_大数据OLAP体系技术栈,Apache Doris,Clickhouse 技术-CSDN博客 🚩 私聊博主:加入大数据技术讨论群聊,获取更多大数据资料。 🔔 博主个人B栈地址:豹哥教你学编程的个人空间-豹哥教你学编程个人主页-哔哩哔哩视频 目录

大文件快速传输解决办法汇总

在数据传输普及的当今时代&#xff0c;文件体量也在不断的突破它”大“的上线&#xff0c;很多企业也在面临着这类大文件快速传输的烦恼&#xff0c;而且这里面的“大”可不是一般意义的几M,几G的文件&#xff0c;它有可能上T级甚至是PB级别、TB级别的大文件&#xff0c;或者是…

CCNP课程实验-07-OSPF-Trouble-Shooting

目录 实验条件网络拓朴 环境配置开始排错错点1&#xff1a;R1-R2之间认证不匹配错误2&#xff1a;hello包的时间配置不匹配错误3&#xff1a;R2的e0/1接口区域配置不正确错误4&#xff1a;R4的e0/1接口没有配置进OSPF错误5&#xff1a;R2的区域1没有配置成特殊区域错误6&#x…

文件摆渡系统如何实现网络隔离后的数据交换、业务流转?

近年来全球网络安全威胁态势的加速严峻&#xff0c;使得企业对于网络安全有了前所未有的关注高度。即便没有行业性的强制要求&#xff0c;但在严峻的安全态势之下&#xff0c;企业的网络安全体系建设正从“以合规为导向”转变到“以风险为导向”&#xff0c;从原来的“保护安全…

SpringCloud微服务安全之API审计日志功能实现

SpringCloud微服务安全之API审计日志功能实现 1.审计功能介绍2.记录的实体类设计3.保存审计记录到数据库的工具4.审计功能实现1.审计功能介绍 审计日志 定义:谁,在什么时间,干了什么事。位置:认证之后,授权之前。这样就知道是谁在访问,拒绝掉的访问也能被记录。如果放在认…

分享10篇优秀论文,涉及图神经网络、大模型优化、表格分析

引言 第38届AAAI人工智能年度会议将于2024年2月在加拿大温哥华举行。今天给大家分享十篇AAAI2024论文&#xff0c;主要涉及图神经网络&#xff0c;大模型幻觉、中文书法文字生成、表格数据分析、KGs错误检测、多模态Prompt、思维图生成等。 论文获取方式&#xff0c;回复&am…

微服务实战系列之Dubbo(下)

前言 眼看着2023即将走远&#xff0c;心里想着似乎还有啥&#xff0c;需要再跟各位盆友叨叨。这不说曹操&#xff0c;曹操就来了。趁着上一篇Dubbo博文的余温尚在&#xff0c;博主兴匆匆地“赶制”了Dubbo的下集&#xff0c;以飨读者。 上一篇博主依然从Dubbo的内核出发&#…

C++第四天

定义一个Person类&#xff0c;私有成员int age&#xff0c;string &name&#xff0c;定义一个Stu类&#xff0c;包含私有成员double *score&#xff0c;写出两个类的构造函数、析构函数、拷贝构造和拷贝赋值函数&#xff0c;完成对Person的运算符重载(算术运算符、条件运算…

Winform中使用Fleck实现Websocket服务端并读取SQLite数据库中数据定时循环群发消息

场景 Winform中使用Websocket4Net实现Websocket客户端并定时存储接收数据到SQLite中&#xff1a; Winform中使用Websocket4Net实现Websocket客户端并定时存储接收数据到SQLite中-CSDN博客 Winform中操作Sqlite数据增删改查、程序启动时执行创建表初始化操作&#xff1a; Wi…

docker 安装可视化工具 Portainer 以及 汉化

安装portainer是最新版本&#xff0c;汉化指定版本2.9.1 。如果要安装汉化版&#xff0c;可直接跳转步骤四 一、拉去镜像 安装网址&#xff1a;Install Portainer BE with Docker on Linux - Portainer Documentation docker pull portainer/portainer二、根据portainer镜像创建…

利用 PEB_LDR_DATA 结构枚举进程模块信息

1. 引言 我们常常通过很多方法来获取进程的模块信息&#xff0c;例如 EnumProcessModules 函数、CreateToolhelp32Snapshot 函数、WTSEnumerateProcesses 函数、ZwQuerySystemInformation 函数等。但是调用这些接口进行模块枚举的原理是什么我们并不知道。通过学习 PEB 中 PEB…

Prometheus-AlertManager 邮件告警

环境,软件准备 本次演示环境&#xff0c;我是在虚拟机上安装 Linux 系统来执行操作&#xff0c;以下是安装的软件及版本&#xff1a; System: CentOS Linux release 7.6Docker: 24.0.5Prometheus: v2.37.6Consul: 1.6.1 docker 安装prometheus,alertmanage,说明一下这里直接将…

ArrayList学生管理系统

文章目录 1.ArrayList集合和数组的优势对比&#xff1a;1.1 ArrayList类概述1.2 ArrayList类常用方法1.2.1 构造方法1.2.2 成员方法1.2.3 示例代码 1.3 ArrayList存储字符串并遍历1.3.1 案例需求1.3.2 代码实现 1.4 ArrayList存储学生对象并遍历1.4.1 案例需求1.4.2 代码实现 1…

【LLM】大型语言模型综述论文

今天我将与大家分享一篇精彩的论文。这项调查提供了LLM文献的最新综述&#xff0c;这对研究人员和工程师来说都是一个有用的资源。 为什么选择LLM&#xff1f; 当参数尺度超过一定水平时&#xff0c;这些扩展的语言模型不仅实现了显著的性能改进&#xff0c;而且还表现出一些…

uniCloud 云数据库(新建表、增、删、改、查)

新建表结构描述文件 todo 为自定义的表名 表结构描述文件的默认后缀为 .schema.json 设置表的操作权限 uniCloud-aliyun/database/todo.schema.json 默认的操作权限都是 false "permission": {"read": false,"create": false,"update&quo…

【熔断限流组件resilience4j和hystrix】

文章目录 &#x1f50a;博主介绍&#x1f964;本文内容起因resilience4j落地实现pom.xml依赖application.yml配置接口使用 hystrix 落地实现pom.xml依赖启动类上添加注解接口上使用 &#x1f4e2;文章总结&#x1f4e5;博主目标 &#x1f50a;博主介绍 &#x1f31f;我是廖志伟…

华为HCIE-Datacom课程介绍

厦门微思网络HCIE-Datacom课程介绍 一、认证简介 HCIE-Datacom&#xff08;Huawei Certified ICT Expert-Datacom&#xff09;认证是华为认证体系中的顶级认证&#xff0c;HCIE-Datacom认证定位具备坚实的企业网络跨场景融合解决方案理论知识&#xff0c;能够使用华为数通产品…

C语言-环境搭建

文章目录 内容Notepad的安装gcc编译工具的配置 编写软件的安装&#xff1a;软件传送门&#xff1a;Notepad软件选择一个合适的路径&#xff0c;一键傻瓜式安装即可 编译工具gcc在windows环境下的配置&#xff1a;解压gcc编辑工具包解压出来的mingw64文件放到一个合适的磁盘路径…

从0到1入门C++编程——03 内存分区、引用、函数高级应用

文章目录 一、内存分区二、引用三、函数的高级应用1.默认参数2.占位参数3.函数重载 一、内存分区 C程序在执行时&#xff0c;会将内存大致分为4个区&#xff0c;分别是代码区、全局区、栈区和堆区。 代码区用来存放函数体和二进制代码&#xff0c;由操作系统进行管理。 全局区…

Kubernetes-网络

一. 前言 flannel两种容器跨主机通信的方案&#xff0c;其中UDP模式是IP in UDP&#xff0c;即三层报文封装在UDP数据包中通信&#xff1b;而vxlan模式则是MAC in UDP&#xff0c;即二层报文封装在UDP数据包中通信 flannel UDP模式和vxlan模式都对数据包做了封解包&#xff0c…