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

时间:2018-09-12 09:08:49

标签: android canvas android-imageview android-bitmap pinchzoom

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

2 个答案:

答案 0 :(得分:0)

在这里写下所有内容将太广泛了。基本上,有很多库可以为ImageView提供缩放手势。

您可以查看他们的代码或也使用该库。这是在github上评价最高的两个。

您只需要使用他们的ImageView,ImageView就会显示手势。像

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

答案 1 :(得分:0)

这只是我项目的一小部分。

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()
    }
}

可以通过这种方式将视图用于xml:-

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