当使用 Samsung S20 将图像代理为位图时,在cameraX 中分析绿色位图

问题描述 投票:0回答:4

我已经使用了底部代码。但它出现绿色位图 当我使用 imageproxy 仅对最新的智能手机进行位图时。 比如三星s20

底部代码在过去的设备上运行良好 谁有问题?

fun Image.toBitmap(): Bitmap {
val yBuffer = planes[0].buffer // Y
val uBuffer = planes[1].buffer // U
val vBuffer = planes[2].buffer // V

val ySize = yBuffer.remaining()
val uSize = uBuffer.remaining()
val vSize = vBuffer.remaining()

val nv21 = ByteArray(ySize + uSize + vSize)

//U and V are swapped
yBuffer.get(nv21, 0, ySize)
vBuffer.get(nv21, ySize, vSize)
uBuffer.get(nv21, ySize + vSize, uSize)

val yuvImage = YuvImage(nv21, ImageFormat.NV21, this.width, this.height, null)
val out = ByteArrayOutputStream()
yuvImage.compressToJpeg(Rect(0, 0, yuvImage.width, yuvImage.height), 50, out)
val imageBytes = out.toByteArray()
return BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.size)
}
android image bitmap android-camerax
4个回答
0
投票
val nv21 = ByteArray(ySize + uSize + vSize)

并非每个

YUV_420_888
缓冲区实际上都是 NV21 格式。您还必须处理其他格式,例如NV12、YU12 和 YV12。 相机示例 Github 存储库上有一个YUV 到位图转换器示例,请尝试一下,它应该可以正常工作。


0
投票

我也遇到过类似的问题。我首先使用低端 Android 设备进行尝试,然后使用高端设备进行尝试,都遇到了同样的问题。

我尝试过的:

  • 另存为 RGB 而不是 YUV
  • 将图像格式从 Nv21 更改为 YUV2
  • 尝试使用自定义函数从 Nv21 转换为其他格式
  • 转换为位图,然后转换为[]字节

没有任何作用。在多种不同质量和年龄的三星、华为和 LG 设备上仍然可以正常工作。

帖子链接:Image.Analyzer 在某些设备上从相机中发出不清楚的图片


0
投票

对我来说,问题在于不同的设备分析视频的速率不同。稍后会详细介绍,但主要问题是,在USING转换后的位图之前使用字节缓冲区从 imageProxy 访问数据。

ImageProxy
对象似乎是硬编码的按引用传递Java对象,这意味着即使您通过状态提升或其他方式将
ImageProxy
从分析器中传递出来,如果您随后在分析方法内修改它的字节,它也会影响传递的值。因此,在代码中的任何位置使用该值之前,请务必调用

<yourImageProxyObject>.planes[index_used].buffer.rewind()

这会将光标移回第零位置,允许读取器访问正确的字节,而不是随机的嘈杂字节。


0
投票

如果您使用的是camerax库

1.3.0
或更高版本,请尝试
imageProxy.toBitmap()
来自Android官方文档

如果您使用的是较低版本,请尝试以下代码


val bitmap = ImageConvertUtils.getInstance().getUpRightBitmap(InputImage.fromMediaImage(image,imageProxy.imageInfo.rotationDegrees))

下面是来自 Google 示例的另一个替代方案

BitmapUtils.java

© www.soinside.com 2019 - 2024. All rights reserved.