Android Matrix绘制PaintDrawable设置BitmapShader,手指触点为圆心scale放大原图,Kotlin(二)

本文主要是介绍Android Matrix绘制PaintDrawable设置BitmapShader,手指触点为圆心scale放大原图,Kotlin(二),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Android Matrix绘制PaintDrawable设置BitmapShader,手指触点为圆心scale放大原图,Kotlin(二)

 

在  Android Matrix绘制PaintDrawable设置BitmapShader,手指触点为圆心scale放大原图,Kotlin-CSDN博客 基础上,限定下面切图的绘制区域,超出绿色区域的轨迹线不再绘制。

 

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.RectF
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.view.MotionEvent
import android.widget.ImageView
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.AppCompatImageViewclass MainActivity : AppCompatActivity() {private var iv: MyImageView? = nulloverride 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 = 0fprivate var mCurY = 0fprivate val mPath1 = Path()private val mPath2 = Path()private val mPathPaint1 = Paint()private val mPathPaint2 = Paint()private val mPathPaint3 = Paint()private val mCirclePaint = Paint()private var mNewBmp: Bitmap? = nullprivate var mSrcBmp: Bitmap? = nullprivate var mIsDraw = falseprivate val mRadius = 380fprivate var mDrawable: PaintDrawable? = nullprivate var testIV: ImageView? = null//放大系数。private val mScaleFactor = 2.6fprivate var mBitmapShader: BitmapShader? = nullconstructor(ctx: Context, attrs: AttributeSet) : super(ctx, attrs) {mSrcBmp = (drawable as BitmapDrawable).bitmap //mSrcBmp是原始图大小,没有缩放和拉伸的。mPathPaint1.style = Paint.Style.STROKEmPathPaint1.strokeWidth = 10fmPathPaint1.isAntiAlias = truemPathPaint1.color = Color.REDmPathPaint2.style = Paint.Style.STROKEmPathPaint2.strokeWidth = 25fmPathPaint2.isAntiAlias = truemPathPaint2.color = Color.YELLOWmPathPaint3.style = Paint.Style.STROKEmPathPaint3.strokeWidth = 3fmPathPaint3.isAntiAlias = truemPathPaint3.color = Color.GREENmCirclePaint.style = Paint.Style.STROKEmCirclePaint.strokeWidth = 30fmCirclePaint.isAntiAlias = truemCirclePaint.color = Color.BLUE}fun setTestImageView(iv: ImageView?) {testIV = iv}override fun onTouchEvent(event: MotionEvent): Boolean {mCurX = event.xmCurY = event.ywhen (event.action) {MotionEvent.ACTION_DOWN -> {mPath1.moveTo(mCurX, mCurY)mPath2.moveTo(mCurX * mScaleFactor, mCurY * mScaleFactor)mIsDraw = true}MotionEvent.ACTION_MOVE -> {mPath1.lineTo(mCurX, mCurY)mPath2.lineTo(mCurX * mScaleFactor, mCurY * mScaleFactor)}MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {mIsDraw = false//抬手后,清除手指轨迹。myClear()}}invalidate()return true}private fun myClear() {//清除历史轨迹。mPath1.reset()mPath2.reset()}override fun onDraw(canvas: Canvas) {super.onDraw(canvas)if (mIsDraw) {myDraw()canvas.drawPath(mPath1, mPathPaint1)}}private fun myDraw() {if (mBitmapShader == null) {//创建一次,避免重复创建,提高速度。mBitmapShader = BitmapShader(Bitmap.createScaledBitmap(mSrcBmp!!,(this.width * mScaleFactor).toInt(), //注意这里的如果精度损失,会造成坐标偏移(this.height * mScaleFactor).toInt(),//注意这里的如果精度损失,会造成坐标偏移true),TileMode.DECAL,TileMode.DECAL)}if (mDrawable == null) {//创建一次,避免重复创建,提高速度。mDrawable = PaintDrawable(Color.BLACK)mDrawable!!.setCornerRadius(mRadius / 2) //圆角矩形,如果不除2即是圆形框图。mDrawable!!.paint.shader = mBitmapShadermDrawable!!.setBounds(0, 0, (mRadius * 2).toInt(), (mRadius * 2).toInt())}if (mNewBmp == null) {//创建一次,避免重复创建,提高速度。mNewBmp = Bitmap.createBitmap(this.width, this.height, Bitmap.Config.ARGB_8888)}val c = Canvas(mNewBmp!!)c.drawColor(Color.GRAY) //底色。val matrix = Matrix()matrix.setScale(mScaleFactor, mScaleFactor)matrix.setTranslate((-mCurX) * mScaleFactor + mRadius, (-mCurY) * mScaleFactor + mRadius)mDrawable!!.paint.shader.setLocalMatrix(matrix)mDrawable!!.draw(c)val rectF = RectF()matrix.mapRect(rectF)val cx = mCurX * mScaleFactor + rectF.leftval cy = mCurY * mScaleFactor + rectF.top//蓝色中心圆圈c.drawCircle(cx, cy, 50f, mCirclePaint)//绿色圆角矩形框。val roundRectPath = Path()val roundRectF = RectF(cx - 250, cy - 250, cy + 250, cy + 250)roundRectPath.addRoundRect(roundRectF, 25f, 25f, Path.Direction.CW)c.drawPath(roundRectPath, mPathPaint3)//限定下面切图中Path绘制轨迹路线的区域,超出边界不绘制。c.clipRect(roundRectF)//下面小框图里面的Pathval path = Path()mPath2.transform(matrix, path)//绘制下面框图里面的Pathc.drawPath(path, mPathPaint2)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.MyImageViewandroid: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" /><ImageViewandroid:id="@+id/result"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="40dp"android:background="@drawable/ic_launcher_background"android:src="@drawable/ic_launcher_foreground" /></LinearLayout>

 

 

b9a13c8d53ba4009b1973a0662120e03.png

 

 

e356425badc64563ac4ad05c206a01c8.png

所有的绘制轨迹线,都限定在了绿色的圆角矩形框中,超出区域不予绘制。

 

 

efe0b152586c4a05a27f1ed8ca2d0fa0.png

 

遗留问题,手指在上图滑动过程中,当滑动到一定区域,下面的切图框中已无太有效的图可以“放大”,后续可以填充黑色,表示无效放大。

 

Android Matrix绘制PaintDrawable设置BitmapShader,手指触点为圆心scale放大原图,Kotlin-CSDN博客文章浏览阅读339次,点赞9次,收藏11次。的基础上,实现一个功能,手指在上面原图的区域滑动,然后在下面的图中以若干放大因子放大显示切块出来的小图,下面切块出来的原图的圆心是手指在上面的触点。同时在下图中复刻上图手指滑动的轨迹。下图的中心圆点用一个圆圈,标识出手指在上图的触点。下图相当于一个放大镜,同时在放大镜图里面显示手指划过的轨迹。遗留一个问题,更好的做法是在下图中只显示圆角矩形切图区域里面的路径,超出圆角矩形切图外的区域,不应该再显示路径。https://blog.csdn.net/zhangphil/article/details/135596459

 

这篇关于Android Matrix绘制PaintDrawable设置BitmapShader,手指触点为圆心scale放大原图,Kotlin(二)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/625996

相关文章

Android协程高级用法大全

《Android协程高级用法大全》这篇文章给大家介绍Android协程高级用法大全,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友跟随小编一起学习吧... 目录1️⃣ 协程作用域(CoroutineScope)与生命周期绑定Activity/Fragment 中手

使用Python实现无损放大图片功能

《使用Python实现无损放大图片功能》本文介绍了如何使用Python的Pillow库进行无损图片放大,区分了JPEG和PNG格式在放大过程中的特点,并给出了示例代码,JPEG格式可能受压缩影响,需先... 目录一、什么是无损放大?二、实现方法步骤1:读取图片步骤2:无损放大图片步骤3:保存图片三、示php

Kotlin 枚举类使用举例

《Kotlin枚举类使用举例》枚举类(EnumClasses)是Kotlin中用于定义固定集合值的特殊类,它表示一组命名的常量,每个枚举常量都是该类的单例实例,接下来通过本文给大家介绍Kotl... 目录一、编程枚举类核心概念二、基础语法与特性1. 基本定义2. 带参数的枚举3. 实现接口4. 内置属性三、

MySQL设置密码复杂度策略的完整步骤(附代码示例)

《MySQL设置密码复杂度策略的完整步骤(附代码示例)》MySQL密码策略还可能包括密码复杂度的检查,如是否要求密码包含大写字母、小写字母、数字和特殊字符等,:本文主要介绍MySQL设置密码复杂度... 目录前言1. 使用 validate_password 插件1.1 启用 validate_passwo

Android 缓存日志Logcat导出与分析最佳实践

《Android缓存日志Logcat导出与分析最佳实践》本文全面介绍AndroidLogcat缓存日志的导出与分析方法,涵盖按进程、缓冲区类型及日志级别过滤,自动化工具使用,常见问题解决方案和最佳实... 目录android 缓存日志(Logcat)导出与分析全攻略为什么要导出缓存日志?按需过滤导出1. 按

Android Paging 分页加载库使用实践

《AndroidPaging分页加载库使用实践》AndroidPaging库是Jetpack组件的一部分,它提供了一套完整的解决方案来处理大型数据集的分页加载,本文将深入探讨Paging库... 目录前言一、Paging 库概述二、Paging 3 核心组件1. PagingSource2. Pager3.

python设置环境变量路径实现过程

《python设置环境变量路径实现过程》本文介绍设置Python路径的多种方法:临时设置(Windows用`set`,Linux/macOS用`export`)、永久设置(系统属性或shell配置文件... 目录设置python路径的方法临时设置环境变量(适用于当前会话)永久设置环境变量(Windows系统

Go语言编译环境设置教程

《Go语言编译环境设置教程》Go语言支持高并发(goroutine)、自动垃圾回收,编译为跨平台二进制文件,云原生兼容且社区活跃,开发便捷,内置测试与vet工具辅助检测错误,依赖模块化管理,提升开发效... 目录Go语言优势下载 Go  配置编译环境配置 GOPROXYIDE 设置(VS Code)一些基本

小白也能轻松上手! 路由器设置优化指南

《小白也能轻松上手!路由器设置优化指南》在日常生活中,我们常常会遇到WiFi网速慢的问题,这主要受到三个方面的影响,首要原因是WiFi产品的配置优化不合理,其次是硬件性能的不足,以及宽带线路本身的质... 在数字化时代,网络已成为生活必需品,追剧、游戏、办公、学习都离不开稳定高速的网络。但很多人面对新路由器

Kotlin Map映射转换问题小结

《KotlinMap映射转换问题小结》文章介绍了Kotlin集合转换的多种方法,包括map(一对一转换)、mapIndexed(带索引)、mapNotNull(过滤null)、mapKeys/map... 目录Kotlin 集合转换:map、mapIndexed、mapNotNull、mapKeys、map