最近做音视频,需要做缩放位移等手势操作。

但OpenGL的坐标体系跟安卓View不一样,屏幕中点(0,0)如图

捣鼓了一天,顺利解决了,纪录一下,主要方法如下

object MatrixUtils {

    //<editor-fold defaultstate="collapsed" desc="矩阵转换">
    private val mMatrix = Matrix()
    private val mMatrixValues = FloatArray(9)
    private val transformMapTemp = floatArrayOf(0f, 0f)
    /**
     * SDK矩阵数据转换
     * @param matrix 矩阵
     * @param width 宽
     * @param height 高
     * @return [缩放,位移,偏移X,偏移Y]
     */
    fun transformSDKMatrix(matrix: Matrix, width: Int, height: Int): FloatArray {
        val halfWidth = width / 2f
        val halfHeight = height / 2f
        val angle = getMatrixAngle(matrix)
        val scale = getMatrixScale(matrix)
        val tranX = getMatrixTransX(matrix) / halfWidth
        val tranY = getMatrixTransY(matrix) / halfHeight
        //目标矩阵中心点
        var fixX = scale * halfWidth
        var fixY = scale * halfHeight
        //处理旋转
        mMatrix.setRotate(angle, 0f, 0f)
        transformMapTemp[0] = fixX
        transformMapTemp[1] = fixY
        mMatrix.mapPoints(transformMapTemp)
        //计算目标矩阵与中点距离差
        fixX = transformMapTemp[0] - halfWidth
        fixY = transformMapTemp[1] - halfHeight
        //比例换算
        fixX /= halfWidth
        fixY /= halfHeight
        return floatArrayOf(scale, angle, tranX + fixX, tranY + fixY)
    }
    // </editor-fold>

    /**
     * 获取矩阵偏移X
     */
    fun getMatrixTransX(matrix: Matrix): Float {
        return getMatrixValue(matrix, Matrix.MTRANS_X)
    }

    /**
     * 获取矩阵偏移Y
     */
    fun getMatrixTransY(matrix: Matrix): Float {
        return getMatrixValue(matrix, Matrix.MTRANS_Y)
    }

    /**
     * This method calculates rotation angle for given Matrix object.
     */
    fun getMatrixAngle(matrix: Matrix): Float {
        return (-(atan2(
            getMatrixValue(matrix, Matrix.MSKEW_X).toDouble(),
            getMatrixValue(matrix, Matrix.MSCALE_X).toDouble()
        ) * (180 / Math.PI))).toFloat()
    }

    /**
     * @return - current image scale value.
     * [1.0f - for original image, 2.0f - for 200% scaled image, etc.]
     */
    fun getMatrixScale(matrix: Matrix): Float {
        return sqrt(
            getMatrixValue(matrix, Matrix.MSCALE_X).toDouble().pow(2.0)
                    + getMatrixValue(matrix, Matrix.MSKEW_Y).toDouble().pow(2.0)
        ).toFloat()
    }

    /**
     * This method returns Matrix value for given index.
     *
     * @param matrix     - valid Matrix object
     * @param valueIndex - index of needed value. See [Matrix.MSCALE_X] and others.
     * @return - matrix value for index
     */
    private fun getMatrixValue(matrix: Matrix, @IntRange(from = 0, to = 9) valueIndex: Int): Float {
        matrix.getValues(mMatrixValues)
        return mMatrixValues[valueIndex]
    }

}