美文网首页
1、Camera获取NV21字节数据的竖屏旋转

1、Camera获取NV21字节数据的竖屏旋转

作者: 瑜_1c3e | 来源:发表于2020-04-24 11:39 被阅读0次

YUV数据格式在这儿已经说得很好了:[https://www.jianshu.com/p/3e44c2262775](https://www.jianshu.com/p/3e44c2262775)

1、获取camera的最佳预览尺寸

(1)、如果已经设置好了,通过以下方法直接获取

````

val size = mCamera.parameters.previewSize

````

(2)、最佳尺寸获取方法可以参考以下函数

````

fun findCameraBestPreviewSize(context: Context, camera: Camera?): Point? {

        if(camera == null) {

            return null

        }

        val manager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager

        val display = manager.defaultDisplay

        val point = Point()

        try {

            display.getSize(point)

        } catch (ignore: NoSuchMethodError) {

            point.x = display.width

            point.y = display.height

        }

        val orientation = context.resources.configuration.orientation

        var width = 0

        var height = 0

        if (orientation == Configuration.ORIENTATION_PORTRAIT) {

            //竖屏情况

            width = point.y

            height = point.x

        } else {

            //横屏情况

            width = point.x

            height = point.y

        }

        val previewSizes = camera.parameters.supportedPreviewSizes

        for (size in previewSizes) {

            if (size.width == width && size.height == height) {

                return Point(width, height)

            }

        }

        val reqRatio = width.toFloat() / height

        //找到 摄像头预览比例 和 屏幕比例最接近的 预览尺寸

        var min = java.lang.Float.MAX_VALUE

        var retSize: Camera.Size? = null

        for (size in previewSizes) {

            val deltaRatio = abs(reqRatio - size.width.toFloat() / size.height)

            if (deltaRatio < min) {

                min = deltaRatio

                retSize = size

            }

        }

        return if (retSize == null) null else Point(retSize.width, retSize.height)

    }

````

2、camera的预览尺寸表示实际的YUV数据内,Y数据的数量

此处camera返回数据为NV21数据,【具体格式问题请参考上述YUV数据格式解析的博客链接】,与下图格式(NV12)类似,不过NV21V在前U在后:

![image](https://img.haomeiwen.com/i10186620/8064ea705974d2cd.png?imageMogr2/auto-orient/strip|imageView2/2/w/860/format/webp)

````

// data:预览返回的字节数组,width:camera预览尺寸宽度, height:camera预览尺寸高度

private fun rotateYuv420SP(data: ByteArray?, width: Int, height: Int): ByteArray? {

        if (data == null) {

            return null

        }

        //YUV420sp(nv21格式:V 前 U 后)Y和UV的数量比为:2:1

        if (data.size != width * height * 3 / 2) {

            return null

        }

        //竖屏下需要旋转

        var k = 0

        val rotatedData = ByteArray(data.size)

        //翻转 Y

        for (j in 0 until width) {

            for (i in (height - 1) downTo 0) {

                rotatedData[k++] = data[i * width + j]

            }

        }

        val uvWidth = width

        val uvHeight = height / 2

        //翻转 UV

        for (j in 0 until uvWidth step 2) {

            for (i in (uvHeight + height - 1) downTo (height)) {

                rotatedData[k++] = data[i * uvWidth + j]

                rotatedData[k++] = data[i * uvWidth + j + 1]

            }

        }

        return rotatedData

    }

````

相关文章

网友评论

      本文标题:1、Camera获取NV21字节数据的竖屏旋转

      本文链接:https://www.haomeiwen.com/subject/rlgxwhtx.html