yuvToMat icon indicating copy to clipboard operation
yuvToMat copied to clipboard

Yuv format is not supported

Open zzxjl1 opened this issue 5 years ago • 3 comments

The problem happens when set the resolution to 2160x1080.

zzxjl1 avatar Jan 14 '20 13:01 zzxjl1

`/**

  • Thrown by [YuvImage.Factory.invoke] for non supported yuv formats.
  • According to the Android documentation no phone should encounter this exception. */`

I AM.

zzxjl1 avatar Jan 14 '20 13:01 zzxjl1

Hi, this bug can be reproduced by using new CameraX library and if you put setTargetResolution method inside your ImageAnalysis. It it really weird, because if setTargetResolution method is not called image.yuv() works perfectly.

I am really sorry but i do not have many time to investigate that bug so in my code i replace it by a lot slower method, but maybe this snippet from stackoverflow will help you:

fun imageToMat(image: Image): Mat { var buffer: ByteBuffer var rowStride: Int var pixelStride: Int val width = image.width val height = image.height var offset = 0 val planes = image.planes val data = ByteArray( image.width * image.height * ImageFormat.getBitsPerPixel(ImageFormat.YUV_420_888) / 8) val rowData = ByteArray(planes[0].rowStride) for (i in planes.indices) { buffer = planes[i].buffer rowStride = planes[i].rowStride pixelStride = planes[i].pixelStride val w = if (i == 0) width else width / 2 val h = if (i == 0) height else height / 2 for (row in 0 until h) { val bytesPerPixel = ImageFormat.getBitsPerPixel(ImageFormat.YUV_420_888) / 8 if (pixelStride == bytesPerPixel) { val length = w * bytesPerPixel buffer[data, offset, length] if (h - row != 1) { buffer.position(buffer.position() + rowStride - length) } offset += length } else { if (h - row == 1) { buffer[rowData, 0, width - pixelStride + 1] } else { buffer[rowData, 0, rowStride] } for (col in 0 until w) { data[offset++] = rowData[col * pixelStride] } } } } val mat = Mat(height + height / 2, width, CvType.CV_8UC1) mat.put(0, 0, data) return mat }

Shusek avatar Jan 27 '20 17:01 Shusek

try { mat = Yuv.rgb(image); // YUV_420_888 to Mat(RGB) } catch (Exception e) { // destory camera activity and start it with another resolution } After some debuging, i came up with this method and it works fine now.

zzxjl1 avatar Jan 28 '20 08:01 zzxjl1