首页 > 解决方案 > Android - 缩放缩放后从图像视图中查找原始 X 和 Y 点

问题描述

我正在构建一个“找到不同”的应用程序,我现在陷入了一段时间的问题。我的应用程序从数据源接收 X 和 Y 点,当用户触摸他所拥有的那个点的范围时“发现不同”。

问题是我创建了一个新功能,让用户放大并移动以获得更好的图像视图......当他触摸图像时 x 和 y 不正确

我试图在比例和翻译之前找到原点。

我的代码的相关部分:

private inner class MyGestureListener : GestureDetector.SimpleOnGestureListener() {

    override fun onSingleTapConfirmed(e: MotionEvent): Boolean {
        if (e.action == MotionEvent.ACTION_UP && SystemClock.elapsedRealtime() - GlobalEventHelper.lastClickTime < TOUCH_DEBOUNCE_TIME) {
            return true
        }
        GlobalEventHelper.lastClickTime = SystemClock.elapsedRealtime()
        callback.onImageTap(e, SharedZoomImageValues.zoomScale)
        return true
    }
    
    override fun onDoubleTap(e: MotionEvent?): Boolean {
        resetZoom()
        callback.onImageMovement(id)
        return true
    }

    override fun onDown(motionEvent: MotionEvent): Boolean {
        val currentPoint = PointF(motionEvent.x, motionEvent.y)
        SharedZoomImageValues.lastPoint.set(currentPoint)
        SharedZoomImageValues.startPoint.set(SharedZoomImageValues.lastPoint)
        imageMatrix = SharedZoomImageValues.touchMatrix
        callback.onImageMovement(id)
        return false
    }

    override fun onScroll(e1: MotionEvent?, e2: MotionEvent?, distanceX: Float, distanceY: Float): Boolean {
        if (SharedZoomImageValues.eImageState == EImageState.DRAG || SharedZoomImageValues.eImageState == EImageState.ZOOM) {
            val currentPoint = PointF(e2!!.x, e2.y)
            val dx = currentPoint.x - SharedZoomImageValues.lastPoint.x
            val dy = currentPoint.y - SharedZoomImageValues.lastPoint.y
            val fixTransX = getFixDragTrans(dx, SharedZoomImageValues.viewWidth.toFloat(), SharedZoomImageValues.origWidth * SharedZoomImageValues.zoomScale)
            val fixTransY = getFixDragTrans(dy, SharedZoomImageValues.viewHeight.toFloat(), SharedZoomImageValues.origHeight * SharedZoomImageValues.zoomScale)
            SharedZoomImageValues.touchMatrix.postTranslate(fixTransX, fixTransY)
            fixTranslation()
            SharedZoomImageValues.lastPoint[currentPoint.x] = currentPoint.y
            imageMatrix = SharedZoomImageValues.touchMatrix
            callback.onImageMovement(id)
        }
        return false
    }
}

private inner class ScaleListener : ScaleGestureDetector.SimpleOnScaleGestureListener() {
    override fun onScaleBegin(detector: ScaleGestureDetector): Boolean {

        if (!isZoomEnabled) {
            return true
        }

        SharedZoomImageValues.eImageState = EImageState.ZOOM
        return true
    }

    override fun onScale(detector: ScaleGestureDetector): Boolean {

        if (!isZoomEnabled) {
            return true
        }

        SharedZoomImageValues.scaleFocusX = detector.focusX
        SharedZoomImageValues.scaleFocusY = detector.focusY
        SharedZoomImageValues.scaleScaleFactor = detector.scaleFactor
        scaleImage(detector.scaleFactor, detector.focusX, detector.focusY)
        callback.onImageMovement(id)
        return true
    }
}

private fun scaleImage(deltaScale: Float, focusX: Float, focusY: Float) {
    var saleFactor = deltaScale
    val prevScale = SharedZoomImageValues.zoomScale
    SharedZoomImageValues.zoomScale *= saleFactor
    if (SharedZoomImageValues.zoomScale > SharedZoomImageValues.mMaxScale) {
        SharedZoomImageValues.zoomScale = SharedZoomImageValues.mMaxScale
        saleFactor = SharedZoomImageValues.mMaxScale / prevScale
    } else if (SharedZoomImageValues.zoomScale < SharedZoomImageValues.mMinScale) {
        SharedZoomImageValues.zoomScale = SharedZoomImageValues.mMinScale
        saleFactor = SharedZoomImageValues.mMinScale / prevScale
    }
    if (SharedZoomImageValues.origWidth * SharedZoomImageValues.zoomScale <= SharedZoomImageValues.viewWidth || SharedZoomImageValues.origHeight * SharedZoomImageValues.zoomScale <= SharedZoomImageValues.viewHeight) {
        SharedZoomImageValues.touchMatrix.postScale(saleFactor, saleFactor, SharedZoomImageValues.viewWidth / 2.toFloat(), SharedZoomImageValues.viewHeight / 2.toFloat())
    } else {
        SharedZoomImageValues.touchMatrix.postScale(saleFactor, saleFactor, focusX, focusY)
    }
    fixTranslation()
}


private fun fixTranslation() {
    SharedZoomImageValues.touchMatrix.getValues(SharedZoomImageValues.floatMatrix) //put matrix values into a float array so we can analyze
    val transX = SharedZoomImageValues.floatMatrix[Matrix.MTRANS_X] //get the most recent translation in x direction
    val transY = SharedZoomImageValues.floatMatrix[Matrix.MTRANS_Y] //get the most recent translation in y direction
    val fixTransX = getFixTranslation(transX, SharedZoomImageValues.viewWidth.toFloat(), SharedZoomImageValues.origWidth * SharedZoomImageValues.zoomScale)
    val fixTransY = getFixTranslation(transY, SharedZoomImageValues.viewHeight.toFloat(), SharedZoomImageValues.origHeight * SharedZoomImageValues.zoomScale)
    if (fixTransX != 0f || fixTransY != 0f) {
        SharedZoomImageValues.touchMatrix.postTranslate(fixTransX, fixTransY)
    }
}

private fun getFixTranslation(trans: Float, viewSize: Float, contentSize: Float): Float {
    val minTrans: Float
    val maxTrans: Float
    if (contentSize <= viewSize) { // case: NOT ZOOMED
        minTrans = 0f
        maxTrans = viewSize - contentSize
    } else { //CASE: ZOOMED
        minTrans = viewSize - contentSize
        maxTrans = 0f
    }
    if (trans < minTrans) { // negative x or y translation (down or to the right)
        return -trans + minTrans
    }
    if (trans > maxTrans) { // positive x or y translation (up or to the left)
        return -trans + maxTrans
    }
    return 0F
}

private fun getFixDragTrans(delta: Float, viewSize: Float, contentSize: Float): Float {
    return if (contentSize <= viewSize) {
        0F
    } else delta
}

水龙头部分:

private fun onImageClicked(touchX: Float, touchY: Float) {

    Log.d(TAG, "onImageClicked: touchX: $touchX,  touchY:$touchY")
    // the x and y point keep changing while zooming and scrolling
    
}

标签: androidmatrixpinchzoomgesturedetector

解决方案


推荐阅读