Android挖取原图手指触点区域RectF(并框线标记)放大到ImageView宽高与矩阵mapRadius,Kotlin
这里 Android挖取原图中心区域RectF(并框线标记)放大到ImageView宽高,Kotlin-CSDN博客 实现的是把原图中心区域的一片小图挖取出来放大放到下面的ImageView里面,现在不再固定中心位置,而是以手指在上图的触点位置为中心位置,挖取一片区域图放大,然后放到下面的ImageView里面。
文章来源地址https://www.toymoban.com/news/detail-839138.html
<?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:clickable="true"
android:scaleType="fitCenter"
android:src="@mipmap/image" />
<ImageView
android:id="@+id/result"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
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.os.Bundle
import android.util.AttributeSet
import android.util.Log
import android.util.SizeF
import android.view.MotionEvent
import android.widget.ImageView
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.AppCompatImageView
import androidx.core.content.ContextCompat
import androidx.core.graphics.toRect
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val miv = findViewById<MyImageView>(R.id.iv)
val iv = findViewById<ImageView>(R.id.result)
miv.setResultImage(iv)
}
}
class MyImageView : AppCompatImageView {
private var W = 0
private var H = 0
private val mSizeF = SizeF(400f, 200f)
private var mOriginBmp: Bitmap? = null
private var mPaint = Paint()
private var result: ImageView? = null
private var mTouchX = 0f
private var mTouchY = 0f
private var mCanDraw = false
private var mCircleRadius = 30f
constructor(ctx: Context, attrs: AttributeSet) : super(ctx, attrs) {
mPaint.style = Paint.Style.STROKE
mPaint.strokeWidth = 5f
mPaint.isAntiAlias = true
mPaint.color = Color.RED
mOriginBmp = getOriginalBitmap(ctx, R.mipmap.image)
Log.d("fly", "origin bmp w=${mOriginBmp!!.width} h=${mOriginBmp!!.height}")
}
private fun getOriginalBitmap(ctx: Context, resId: Int): Bitmap {
val options = BitmapFactory.Options()
options.inJustDecodeBounds = true //只解析原始图片的宽高,不decode原始文件装载到内存的Bitmap。
BitmapFactory.decodeResource(resources, resId, options)
//这一阶段,最关键的是获取原始图的真实宽高。
val srcBmpWidth = options.outWidth
val srcBmpHeight = options.outHeight
val d = ContextCompat.getDrawable(ctx, resId)
//根据原始图片的宽高创建一个空的Bitmap
val bitmap = Bitmap.createBitmap(srcBmpWidth, srcBmpHeight, Bitmap.Config.ARGB_8888)
val canvas = Canvas(bitmap)
d?.setBounds(0, 0, srcBmpWidth, srcBmpHeight)
d?.draw(canvas) //至此,bitmap即为原始图片。
return bitmap
}
override fun onTouchEvent(event: MotionEvent?): Boolean {
if (event == null) {
return false
}
mTouchX = event.x
mTouchY = event.y
when (event.action) {
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
mCanDraw = true
myInvalidate()
}
}
return super.onTouchEvent(event)
}
private fun myInvalidate() {
this.invalidate()
}
fun setResultImage(iv: ImageView) {
result = iv
}
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
super.onSizeChanged(w, h, oldw, oldh)
W = w
H = h
Log.d("fly", "W=$W H=$H")
}
//从原始的Bitmap图中抠出一块SizeF大小的图。
private fun getCenterBmp(): Bitmap {
val bmp = Bitmap.createBitmap(W, H, Bitmap.Config.ARGB_8888)
val c = Canvas(bmp)
val dstRectF = RectF(0f, 0f, bmp.width.toFloat(), bmp.height.toFloat())
//需要特别注意,要把手指在屏幕上触点坐标,经过比例映射到原始图Bitmap的对应位置。
val mapToOriginBmpX = mOriginBmp!!.width * (mTouchX / W)
val mapToOriginBmpY = mOriginBmp!!.height * (mTouchY / H)
val centerRectF =
RectF(
mapToOriginBmpX - mSizeF.width / 2f,
mapToOriginBmpY - mSizeF.height / 2f,
mapToOriginBmpX + mSizeF.width / 2f,
mapToOriginBmpY + mSizeF.height / 2f
)
c.drawBitmap(mOriginBmp!!, centerRectF.toRect(), dstRectF, null)
val mx = Matrix()
mx.setScale(dstRectF.width() / centerRectF.width(), dstRectF.width() / centerRectF.width())
//下面图中的中心圆圈。
mPaint.color = Color.YELLOW
c.drawCircle(
W / 2f, H / 2f,
mx.mapRadius(mCircleRadius), //注意同步放大小图的圆圈半径。
mPaint
)
return bmp
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
if (mCanDraw) {
//绘制中心圆圈。
mPaint.color = Color.YELLOW
canvas.drawCircle(mTouchX, mTouchY, mCircleRadius, mPaint)
drawRoundRectLine(canvas)
result?.setImageBitmap(getCenterBmp())
mCanDraw = false
}
}
private fun drawRoundRectLine(canvas: Canvas) {
val lineRectF = RectF(
0f,
0f,
mSizeF.width,
mSizeF.height
)
//原始图被Android系统拉伸放到屏幕上,所以lineRectF也需要进行相同的拉伸。
val originBmpSizeMapMatrix = Matrix()
originBmpSizeMapMatrix.setScale(getOriginBmpScaleToImageViewFactor(), getOriginBmpScaleToImageViewFactor())
originBmpSizeMapMatrix.mapRect(lineRectF)
lineRectF.offset(mTouchX - lineRectF.width() / 2f, mTouchY - lineRectF.height() / 2f)
//绘制红色的lineRectF线框。
val path = Path()
path.addRoundRect(lineRectF, 20f, 20f, Path.Direction.CW)
mPaint.color = Color.RED
canvas.drawPath(path, mPaint)
}
private fun getOriginBmpScaleToImageViewFactor(): Float {
return (W.toFloat()) / (mOriginBmp!!.width)
}
}
运行后,点击上图不同位置点:
Android BitmapFactory.decodeResource读取原始图片装载成原始宽高Bitmap,Kotlin_bitmapfactory解码宽高-CSDN博客文章浏览阅读856次。文章浏览阅读1.8k次。/*Java代码 将Drawable转化为Bitmap */ Bitmap drawableToBitmap(Drawable drawable) { int width = drawable.getIntrinsicWidth();Android Drawable 转化成 Bitmap-CSDN博客。_bitmapfactory解码宽高https://blog.csdn.net/zhangphil/article/details/134449577
Android挖取原图中心区域RectF(并框线标记)放大到ImageView宽高,Kotlin-CSDN博客文章浏览阅读395次,点赞11次,收藏11次。文章浏览阅读853次。【代码】Android矩阵setRectToRect裁剪Bitmap原图Matrix放大,mapRect标记中心区域,Kotlin。Android BitmapFactory.decodeResource读取原始图片装载成原始宽高Bitmap,Kotlin_bitmapfactory解码宽高-CSDN博客。Android矩阵setRectToRect裁剪Bitmap原图Matrix放大,mapRect标记中心区域,Kotlin-CSDN博客。https://blog.csdn.net/zhangphil/article/details/136157116文章来源:https://www.toymoban.com/news/detail-839138.html
到了这里,关于Android挖取原图手指触点区域RectF(并框线标记)放大到ImageView宽高与矩阵mapRadius,Kotlin的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!