美文网首页
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