Android挖取原图中心区域RectF(并框线标记)放大到ImageView宽高,Kotlin
红色线框区域即为选中的原图中心区域,放大后放到等宽高的ImageView里面。
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.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
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
}
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())
val cx = mOriginBmp!!.width / 2f
val cy = mOriginBmp!!.height / 2f
val centerRectF = RectF(cx - mSizeF.width / 2f, cy - mSizeF.height / 2f, cx + mSizeF.width / 2f, cy + mSizeF.height / 2f)
c.drawBitmap(mOriginBmp!!, centerRectF.toRect(), dstRectF, null)
return bmp
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
//绘制中心圆圈。
mPaint.color = Color.YELLOW
canvas.drawCircle(W / 2f, H / 2f, 40f, mPaint)
drawRoundRectLine(canvas)
result?.setImageBitmap(getCenterBmp())
}
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)
//注意移动到中心位置,ImageView的中心位置。
lineRectF.offset(W / 2f - lineRectF.width() / 2f, H / 2f - 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.toFloat())
}
}
<?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:scaleType="fitCenter"
android:src="@mipmap/image" />
<ImageView
android:id="@+id/result"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
Android矩阵setRectToRect裁剪Bitmap原图Matrix放大,mapRect标记中心区域,Kotlin-CSDN博客文章浏览阅读419次,点赞3次,收藏6次。【代码】Android矩阵setRectToRect裁剪Bitmap原图Matrix放大,mapRect标记中心区域,Kotlin。https://blog.csdn.net/zhangphil/article/details/135960921
Android BitmapFactory.decodeResource读取原始图片装载成原始宽高Bitmap,Kotlin_bitmapfactory解码宽高-CSDN博客文章浏览阅读853次。文章浏览阅读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