简体   繁体   English

如何捏缩放从图库中选取的图像

[英]How to pinch zoom an image picked from gallery

我开始开发一个编辑应用程序,可以从图库到应用程序拍摄图像,但是我不知道如何捏缩放和平移请有人告诉我怎么做

It was a small part of my project. 这只是我项目的一小部分。

class ZoomView @JvmOverloads constructor(
        context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : ImageView(context, attrs, defStyleAttr) {

    private val imageBound = RectF()
    private val imageMatrixArray = FloatArray(9)
    private val scaleDetector: ScaleGestureDetector

    private var scale: Float = 1f
    private var scalePoint = PointF()
    private var translateX: Float = 0f
    private var translateY: Float = 0f
    private var lastTouchX = 0f
    private var lastTouchY = 0f
    private var lastDownTouchX = 0f
    private var lastDownTouchY = 0f
    private var lastGestureX = 0f
    private var lastGestureY = 0f
    private var isScaling = false
    private var activePointerId = -1
    private var drawableHeight = -1.0
    private var drawableWidth = -1.0
    private var minBoxRectSide = 0

    init {

        scaleDetector = ScaleGestureDetector(context, object : ScaleGestureDetector
        .SimpleOnScaleGestureListener() {
            override fun onScaleBegin(detector: ScaleGestureDetector?): Boolean {
                isScaling = true
                return super.onScaleBegin(detector)
            }

            override fun onScale(detector: ScaleGestureDetector): Boolean {
                scale *= detector.scaleFactor
                scale = Math.min(scale, 25f)
                scale = Math.max(0.5f, scale)

                invalidate()
                return true
            }

            override fun onScaleEnd(detector: ScaleGestureDetector?) {
                super.onScaleEnd(detector)
                isScaling = false
            }
        })
    }

    override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
        super.onLayout(changed, left, top, right, bottom)
        //Timber.d("Image on layout : layoutChanged = $changed")
        if (changed) {
            drawable?.let {
                resetBoxRect(it, left, right, top, bottom)
            }
        }
    }

    private fun resetBoxRect(it: Drawable, left: Int, right: Int, top: Int, bottom: Int) {
        //Timber.d("image coordinates $left, $top, $right, $bottom")

        drawableHeight = it.intrinsicHeight.toDouble()
        drawableWidth = it.intrinsicWidth.toDouble()

        imageMatrix.getValues(imageMatrixArray)
        imageBound.set((left + right) / 2 - imageMatrixArray[Matrix.MSCALE_X] * it.intrinsicWidth / 2,
                (bottom - top) / 2 - imageMatrixArray[Matrix.MSCALE_Y] * it.intrinsicHeight / 2,
                (left + right) / 2 + imageMatrixArray[Matrix.MSCALE_X] * it.intrinsicWidth / 2,
                (bottom - top) / 2 + imageMatrixArray[Matrix.MSCALE_Y] * it.intrinsicHeight / 2)

        //Timber.d("Image bound $imageBound, and $boxRect")
        minBoxRectSide = (.01f * Math.max(imageBound.bottom - imageBound.top, imageBound.right - imageBound.left)).toInt()
        scale = 1f
        translateX = 0f
        translateY = 0f

    }

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        scalePoint.set(w / 2.toFloat(), h / 2.toFloat())
    }

    override fun setImageDrawable(drawable: Drawable?) {
        super.setImageDrawable(drawable)
        drawable?.let {
            if (imageMatrixArray != null) {
                resetBoxRect(it, left, right, top, bottom)
            }
        }
    }

    override fun onTouchEvent(event: MotionEvent): Boolean {
        parent.requestDisallowInterceptTouchEvent(true)
        //Timber.d("On touch start")
        scaleDetector.onTouchEvent(event)
        //Timber.d("On touch gesture sent")
        when (event.actionMasked) {
            MotionEvent.ACTION_DOWN -> onActionDown(event)
            MotionEvent.ACTION_MOVE -> onMoveEvent(event)
            MotionEvent.ACTION_CANCEL -> activePointerId = -1
            MotionEvent.ACTION_UP -> {
                activePointerId = -1
            }
            MotionEvent.ACTION_POINTER_UP -> onActionUp(event)
        }
        return true
    }


    private fun onActionDown(event: MotionEvent) {
        val actionIndex = event.actionIndex
        lastDownTouchX = event.getX(actionIndex)
        lastDownTouchY = event.getY(actionIndex)

        lastTouchX = event.getX(actionIndex)
        lastTouchY = event.getY(actionIndex)
        lastGestureX = lastTouchX
        lastGestureY = lastTouchY
        activePointerId = event.getPointerId(0)

        invalidate()
    }

    private fun onMoveEvent(event: MotionEvent) {
        if (!isScaling) {
            val index = event.findPointerIndex(activePointerId)
            val dx = (event.getX(index) - lastTouchX) / scale
            val dy = (event.getY(index) - lastTouchY) / scale
            lastTouchX = event.getX(index)
            lastTouchY = event.getY(index)

            if (Math.abs(translateX + dx) < imageBound.right - imageBound.left)
                translateX += dx
            if (Math.abs(translateY + dy) < imageBound.bottom - imageBound.top)
                translateY += dy

            invalidate()

        }
    }

    private fun onActionUp(event: MotionEvent) {
        val pointerIndex = event.actionIndex
        val pointerId = event.getPointerId(pointerIndex)
        if (pointerId == activePointerId) {
            // This was our active pointer going up. Choose a new
            // active pointer and adjust accordingly.
            val newPointerIndex = if (pointerIndex == 0) 1 else 0
            lastTouchX = event.getX(newPointerIndex)
            lastTouchY = event.getY(newPointerIndex)
            activePointerId = event.getPointerId(newPointerIndex)
        }
    }

    override fun onDraw(canvas: Canvas) {
        canvas.save()

        canvas.scale(scale, scale, scalePoint.x, scalePoint.y)
        canvas.translate(translateX, translateY)

        super.onDraw(canvas)

        canvas.restore()
    }
}

The view can be used the xml in this way :- 可以通过这种方式使用xml视图:

<com.myproject.app.widgets.ZoomView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:src="@drawable/abc" />

It will be too broad to write here all the things. 在这里写所有的东西太广泛了。 Basically there are lot of libraries which provide ImageView with zoom gesture. 基本上,有很多库可为ImageView提供缩放手势。

You can see their code or use that library as well. 您可以查看他们的代码,也可以使用该库。 Here are two with highest rating on github. 这是在GitHub上评分最高的两个。

You just need to use their ImageView and your ImageView will have the gesture. 您只需要使用他们的ImageView,您的ImageView就会显示手势。 Like 喜欢

<com.github.chrisbanes.photoview.PhotoView
    android:id="@+id/photo_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM