5

I already use bottom code. But It apear green bitmap when I use imageproxy to bitmap only about lastest smartphone. Such as Samsung s20

Bottom code work well on past device Who does have some problem?

enter image description here

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)
}
MeiH
  • 1,763
  • 11
  • 17
You.Brighton
  • 1,958
  • 2
  • 15
  • 22
  • 1
    I know nothing about android-camerax, but it seems that you somehow messed up the column size of the arrays. Check the rows, columns, channels and also the stride again. – MeiH Oct 27 '20 at 08:15
  • Hi @You.Brighton, I am getting the same result but in different device, Can you please provide little bit help regarding this issue? – Bhavnik Feb 25 '22 at 10:00
  • I'm getting this on the same device, but on one of the two apps. It works fine on the other, Android 11 – Richard Onslow Roper May 08 '22 at 19:45

3 Answers3

0
val nv21 = ByteArray(ySize + uSize + vSize)

Not every YUV_420_888 buffer is actually NV21 format. You also have to handle other formats, e.g. NV12, YU12 and YV12. There's a YUV to bitmap converter sample on the camera samples Github repo, try it out, it should work correctly.

Husayn Hakeem
  • 4,184
  • 1
  • 16
  • 31
0

I have been encountering a similar problem. I first tried it using a low-end android device, and then with a high-end device, and both had the same problem.

What I tried:

  • Save as RGB not YUV
  • Change imageFormat from Nv21 to YUV2
  • Try to convert from Nv21 to other formats using custom functions
  • Convert to bitmap and then to []byte

Nothing worked. Still works good on several Samsung, Huawei and LG devices of various qualities and ages.

Link to post:Image.Analyzer gives out unclear picture from camera on certain devices

0

The problem for me turned out to be the fact that different devices have different rates at which they can analyze a video. More on that later, but the main problem was, accessing data from the imageProxy using byte buffers BEFORE USING the converted bitmap. ImageProxy objects seem to be hard-coded pass-by-reference Java objects, which means even if you pass that ImageProxy out of the analyzer via state-hoisting or something, if you then modify it's bytes INSIDE the analyze method, it will affect the passed value too. Hence, before using the value anywhere in your code, be sure to call

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

This shifts the cursor back to the zero-th position, allowing the readers to access the correct bytes instead of random noisy ones.

Richard Onslow Roper
  • 5,477
  • 2
  • 11
  • 42