图片缩放工具类

/**
 *@author River
 *@date 2023/12/26
 *@todo 缩放图片辅助
 */
class PhotoViewAttach constructor(val iv:ImageView) : View.OnTouchListener,View.OnLayoutChangeListener {

    private val SCALE_MAX=3.0f
    private val SCALE_MIN=1.0f
    private val mBaseMatrix=Matrix()
    private val mScaleMatrix=Matrix()
    private val mDrawMatrix=Matrix()

    init {
        iv.addOnLayoutChangeListener(this)
        iv.setOnTouchListener(this)
    }

    private val scaleDetector=ScaleGestureDetector(iv.context,object :ScaleGestureDetector.OnScaleGestureListener{

        override fun onScale(detector: ScaleGestureDetector?): Boolean {
            if(iv.drawable==null||detector==null){
                return true
            }
            val scaleFactor = detector.scaleFactor
            val scale=getScale()
            //最大放大倍数之下可以放大,最小放大倍数之上可以缩小
            if(scale<SCALE_MAX&&scaleFactor>1||scale>SCALE_MIN&&scaleFactor<1){
                LogUtil.d("PhotoViewAttach","onScale scaleFactor=$scaleFactor scale=$scale")
                val resultScale = scale * scaleFactor
                var mScaleFactor=scaleFactor
                if(resultScale<SCALE_MIN){
                    mScaleFactor=SCALE_MIN/scale
                }else if(resultScale>SCALE_MAX){
                    mScaleFactor=SCALE_MAX/scale
                }
                mScaleMatrix.postScale(mScaleFactor,mScaleFactor,detector.focusX,detector.focusY)
                checkBorder()
                setImageView()
            }
            return true
        }

        override fun onScaleBegin(detector: ScaleGestureDetector?): Boolean {
            return true
        }

        override fun onScaleEnd(detector: ScaleGestureDetector?) {

        }
    })

    /**
     * 触摸点不在中心点,会造成缩放后左右上下出现偏移留白,需要动态平移使图片居中显示
     */
    private fun checkBorder() {
        val rect= getDrawableRect() ?: return
        mDrawMatrix.set(mBaseMatrix)
        mDrawMatrix.postConcat(mScaleMatrix)
        mDrawMatrix.mapRect(rect)
        val viewW=iv.width
        val viewH=iv.height
        val rectW=rect.width().toInt()
        val rectH=rect.height().toInt()
        var deltaX=0f
        var deltaY=0f
        if(rectW<=viewW){
            deltaX=(viewW-rectW)/2-rect.left
        }else if(rect.left>0){
            deltaX=-rect.left
        }else if(rect.right<viewW){
            deltaX=viewW-rect.right
        }
        if(rectH<=viewH){
            deltaY=(viewH-rectH)/2-rect.top
        }else if(rect.top>0){
            deltaY=-rect.top
        }else if(rect.bottom<viewH){
            deltaY=viewH-rect.bottom
        }
        mScaleMatrix.postTranslate(deltaX,deltaY)
    }

    private fun setImageView() {
        mDrawMatrix.set(mBaseMatrix)
        mDrawMatrix.postConcat(mScaleMatrix)
        iv.imageMatrix=mDrawMatrix
    }


    private fun getScale(): Float {
        val values= FloatArray(9)
        mScaleMatrix.getValues(values)
        return values[Matrix.MSCALE_X]
    }


    override fun onTouch(v: View?, event: MotionEvent?): Boolean {
        scaleDetector.onTouchEvent(event)
        return true
    }

    override fun onLayoutChange(v: View?, left: Int, top: Int, right: Int, bottom: Int, oldLeft: Int, oldTop: Int, oldRight: Int, oldBottom: Int) {
       LogUtil.d("PhotoViewAttach","onLayoutChange")
        val drawableRect = getDrawableRect()
        if(drawableRect!=null){
            mBaseMatrix.reset()
            val rect2= RectF(0f,0f,iv.width*1.0f,iv.height*1.0f)
            mBaseMatrix.setRectToRect(drawableRect,rect2,Matrix.ScaleToFit.CENTER)
            iv.imageMatrix=mBaseMatrix
        }
    }

    private fun getDrawableRect():RectF?{
        val drawable = iv.drawable ?: return null
        return RectF(0f,0f,drawable.intrinsicWidth*1.0f,drawable.intrinsicHeight*1.0f)
    }

}
  • 8
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值