当前位置:   article > 正文

Android矩阵Matrix动画缩放Bitmap移动手指触点到ImageView中心位置,Kotlin_android 矩阵动画

android 矩阵动画

Android矩阵Matrix动画缩放Bitmap移动手指触点到ImageView中心位置,Kotlin

 

 

 

借鉴 Android双指缩放ScaleGestureDetector检测放大因子大图移动到双指中心点ImageView区域中心,Kotlin(2)-CSDN博客 在此基础上实现手指在屏幕上点击后,动画放大图片,在放大过程中,移动手指触点位置到ImageView的中心。

 

  1. import android.content.Context
  2. import android.graphics.Bitmap
  3. import android.graphics.Canvas
  4. import android.graphics.Color
  5. import android.graphics.Matrix
  6. import android.graphics.Paint
  7. import android.graphics.RectF
  8. import android.graphics.drawable.BitmapDrawable
  9. import android.os.Bundle
  10. import android.util.AttributeSet
  11. import android.util.Log
  12. import android.view.MotionEvent
  13. import androidx.appcompat.app.AppCompatActivity
  14. import androidx.appcompat.widget.AppCompatImageView
  15. import kotlinx.coroutines.CoroutineScope
  16. import kotlinx.coroutines.Dispatchers
  17. import kotlinx.coroutines.delay
  18. import kotlinx.coroutines.launch
  19. class MainActivity : AppCompatActivity() {
  20. override fun onCreate(savedInstanceState: Bundle?) {
  21. super.onCreate(savedInstanceState)
  22. setContentView(R.layout.activity_main)
  23. }
  24. }
  25. class MyImageView : AppCompatImageView {
  26. private var mCurX = 0f
  27. private var mCurY = 0f
  28. private var mCanDrawBitmap = false
  29. private var W = 0
  30. private var H = 0
  31. private val SCALE_FACTOR: Float = 5.5f
  32. private var mOriginBmp: Bitmap? = null
  33. private var mCirclePaint = Paint()
  34. private var mDeltaScaleFactor: Float = 0f
  35. private var mAnimScaleBmp: Bitmap? = null
  36. private var mCanDrawTouchPoint = false
  37. private var mTouchPointX = 0f
  38. private var mTouchPointY = 0f
  39. constructor(ctx: Context, attrs: AttributeSet) : super(ctx, attrs) {
  40. mCirclePaint.style = Paint.Style.STROKE
  41. mCirclePaint.strokeWidth = 10f
  42. mCirclePaint.isAntiAlias = true
  43. mCirclePaint.color = Color.RED
  44. mOriginBmp = (this.drawable as BitmapDrawable).bitmap
  45. }
  46. override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
  47. super.onSizeChanged(w, h, oldw, oldh)
  48. W = w
  49. H = h
  50. Log.d("fly", "W=$W H=$H")
  51. }
  52. override fun onTouchEvent(event: MotionEvent?): Boolean {
  53. if (event == null) {
  54. return false
  55. }
  56. mCurX = event.x
  57. mCurY = event.y
  58. when (event.actionMasked) {
  59. MotionEvent.ACTION_DOWN -> {
  60. //启动动画。
  61. startScaleAnim()
  62. }
  63. }
  64. return false
  65. }
  66. /**
  67. * Bitmap.createScaledBitmap耗时加剧卡顿。
  68. * 优化方案,基于原图setRectToRect缩放到给定宽w高h的放大图。
  69. */
  70. private fun getScaleBmp(w: Int, h: Int): Bitmap {
  71. val bmp = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888)
  72. val c = Canvas(bmp)
  73. c.drawColor(Color.BLUE)
  74. val src = RectF(0f, 0f, mOriginBmp!!.width.toFloat(), mOriginBmp!!.height.toFloat())
  75. val dst = RectF(0f, 0f, w.toFloat(), h.toFloat())
  76. val mx = Matrix()
  77. mx.setRectToRect(src, dst, Matrix.ScaleToFit.CENTER)
  78. c.drawBitmap(mOriginBmp!!, mx, null)
  79. return bmp
  80. }
  81. private fun startScaleAnim() {
  82. val step = 50f //经过step后,完成缩放动画。
  83. val delta = (SCALE_FACTOR - 1) / step
  84. CoroutineScope(Dispatchers.IO).launch {
  85. //绘制在原图上手的触点。
  86. mTouchPointX = mCurX
  87. mTouchPointY = mCurY
  88. mCanDrawTouchPoint = true
  89. myPostInvalidate()
  90. delay(500) //延时,观察手指触点。
  91. mCanDrawTouchPoint = false
  92. mCanDrawBitmap = true
  93. for (i in 0 until step.toInt()) {
  94. mDeltaScaleFactor = 1f + delta * i
  95. /*
  96. mAnimScaleBmp = Bitmap.createScaledBitmap(
  97. mOriginBmp!!,
  98. (W * mDeltaScaleFactor + 1).toInt(), //注意精度损失,造成坐标偏移。
  99. (H * mDeltaScaleFactor + 1).toInt(),//注意精度损失,造成坐标偏移。
  100. true
  101. )
  102. */
  103. mAnimScaleBmp = getScaleBmp((W * mDeltaScaleFactor + 0.5).toInt(), (H * mDeltaScaleFactor + 0.5).toInt())
  104. //触发重绘。
  105. myPostInvalidate()
  106. }
  107. //for循环完成后,绘制最终图片动画放大完成后的中心圆点。
  108. mTouchPointX = W / 2f
  109. mTouchPointY = H / 2f
  110. mCanDrawTouchPoint = true
  111. myPostInvalidate()
  112. }
  113. }
  114. private fun myPostInvalidate() {
  115. this.postInvalidate()
  116. }
  117. private fun drawTouchPoint(c: Canvas) {
  118. c.drawCircle(mTouchPointX, mTouchPointY, 50f, mCirclePaint)
  119. }
  120. override fun onDraw(canvas: Canvas) {
  121. super.onDraw(canvas)
  122. if (mCanDrawBitmap) {
  123. val mx = Matrix()
  124. mx.setScale(mDeltaScaleFactor, mDeltaScaleFactor)
  125. mx.setTranslate(W / 2f - mCurX * mDeltaScaleFactor, H / 2f - mCurY * mDeltaScaleFactor)
  126. canvas.drawBitmap(mAnimScaleBmp!!, mx, null)
  127. }
  128. if (mCanDrawTouchPoint) {
  129. drawTouchPoint(canvas)
  130. }
  131. }
  132. }

 

 

 

 

 

 

 

 

Android双指缩放ScaleGestureDetector检测放大因子大图移动到双指中心点ImageView区域中心,Kotlin(2)-CSDN博客文章浏览阅读613次,点赞4次,收藏5次。需要注意的,因为在xml布局里面特别设置了ImageView的高度为wrap_content,手指在屏幕触点的位置是放大镜里面放大图片后准确圆心位置,但是,如果ImageView设置成match_parent,则因为ImageView里面的Bitmap被缩放(此处Bitmap其实小于ImageView,被拉伸了),拉伸后的Bitmap水平方向坐标与ImageView一直重合,但竖直方向,Bitmap坐标与ImageView不一致,会造成一种现象,手指触点放大镜放大后,水平方向是正确的,但竖直方向有偏移量。https://blog.csdn.net/zhangphil/article/details/135701608Android矩阵setRectToRect裁剪Bitmap原图Matrix放大,mapRect标记中心区域,Kotlin-CSDN博客文章浏览阅读229次,点赞3次,收藏5次。【代码】Android矩阵setRectToRect裁剪Bitmap原图Matrix放大,mapRect标记中心区域,Kotlin。https://blog.csdn.net/zhangphil/article/details/135960921

Android ScaleGestureDetector检测双指缩放Bitmap基于Matrix动画移动到双指捏合中心点ImageView区域中心,Kotlin_android的两指捏合-CSDN博客文章浏览阅读256次,点赞5次,收藏11次。需要注意的,因为在xml布局里面特别设置了ImageView的高度为wrap_content,手指在屏幕触点的位置是放大镜里面放大图片后准确圆心位置,但是,如果ImageView设置成match_parent,则因为ImageView里面的Bitmap被缩放(此处Bitmap其实小于ImageView,被拉伸了),拉伸后的Bitmap水平方向坐标与ImageView一直重合,但竖直方向,Bitmap坐标与ImageView不一致,会造成一种现象,手指触点放大镜放大后,水平方向是正确的,但竖直方向有偏移量。_android的两指捏合https://blog.csdn.net/zhangphil/article/details/135705931

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/303777
推荐阅读
相关标签
  

闽ICP备14008679号