android image-processing imageview yuv

Visualización de la imagen YUV en Android



image-processing imageview (2)

Cree un mapa de bits después de obtener Ancho y alto en onCreate.

editedBitmap = Bitmap.createBitmap(widthPreview, heightPreview, android.graphics.Bitmap.Config.ARGB_8888);

Y en onPreviewFrame.

int[] rgbData = decodeGreyscale(aNv21Byte,widthPreview,heightPreview); editedBitmap.setPixels(rgbData, 0, widthPreview, 0, 0, widthPreview, heightPreview);

Y

private int[] decodeGreyscale(byte[] nv21, int width, int height) { int pixelCount = width * height; int[] out = new int[pixelCount]; for (int i = 0; i < pixelCount; ++i) { int luminance = nv21[i] & 0xFF; // out[i] = Color.argb(0xFF, luminance, luminance, luminance); out[i] = 0xff000000 | luminance <<16 | luminance <<8 | luminance;//No need to create Color object for each. } return out; }

Y Bonus.

if(cameraId==CameraInfo.CAMERA_FACING_FRONT) { matrix.setRotate(270F); } finalBitmap = Bitmap.createBitmap(editedBitmap, 0, 0, widthPreview, heightPreview, matrix, true);

En mi aplicación, necesitamos mostrar el cuadro de video recibido del servidor a nuestra aplicación de Android,
El servidor está enviando datos de video a 50 cuadros por segundo, después de haberlos codificado en WebM, es decir, usando libvpx para codificar y decodificar las imágenes

Ahora, después de decodificar desde libvpx su obtención de datos YUV, podemos mostrarlos en el diseño de la imagen,

La implementación actual es algo como esto,

En el código JNI / Native C ++, estamos convirtiendo datos YUV a datos RGB en el marco de Android, llamando

public Bitmap createImgae(byte[] bits, int width, int height, int scan) { Bitmap bitmap=null; System.out.println("video: creating bitmap"); //try{ bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); bitmap.copyPixelsFromBuffer(ByteBuffer.wrap(bits)); //}catch(OutOfMemoryError ex){ //} System.out.println("video: bitmap created"); return bitmap; }

Para crear la imagen de mapa de bits,

para mostrar la imagen sobre imageView usando el siguiente código,

img = createImgae(imgRaw, imgInfo[0], imgInfo[1], 1); if(img!=null && !img.isRecycled()){ iv.setImageBitmap(img); //img.recycle(); img=null; System.out.println("video: image displayed"); }

Mi consulta es que, en general, esta función está tomando aproximadamente 40 ms, ¿hay alguna forma de optimizarla?
1 - ¿Hay alguna manera de mostrar los datos YUV a imageView?

2 - ¿Hay alguna otra manera de crear Imagen (imagen de mapa de bits) a partir de datos RGB,

3 - Creo que siempre estoy creando una imagen, pero supongo que debería crear un mapa de bits solo una vez y hacer / suministrar un nuevo búfer siempre, como y cuando lo recibimos.
por favor comparta sus puntos de vista.


El siguiente código resuelve su problema y puede llevar menos tiempo en los datos del Formato Yuv porque la clase YuvImage se proporciona con Android-SDK.

Puedes probar esto,

ByteArrayOutputStream out = new ByteArrayOutputStream(); YuvImage yuvImage = new YuvImage(data, ImageFormat.NV21, width, height, null); yuvImage.compressToJpeg(new Rect(0, 0, width, height), 50, out); byte[] imageBytes = out.toByteArray(); Bitmap image = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length); iv.setImageBitmap(image);

o

void yourFunction(byte[] data, int mWidth, int mHeight) { int[] mIntArray = new int[mWidth*mHeight]; // Decode Yuv data to integer array decodeYUV420SP(mIntArray, data, mWidth, mHeight); //Initialize the bitmap, with the replaced color Bitmap bmp = Bitmap.createBitmap(mIntArray, mWidth, mHeight, Bitmap.Config.ARGB_8888); // Draw the bitmap with the replaced color iv.setImageBitmap(bmp); } static public void decodeYUV420SP(int[] rgba, byte[] yuv420sp, int width, int height) { final int frameSize = width * height; for (int j = 0, yp = 0; j < height; j++) { int uvp = frameSize + (j >> 1) * width, u = 0, v = 0; for (int i = 0; i < width; i++, yp++) { int y = (0xff & ((int) yuv420sp[yp])) - 16; if (y < 0) y = 0; if ((i & 1) == 0) { v = (0xff & yuv420sp[uvp++]) - 128; u = (0xff & yuv420sp[uvp++]) - 128; } int y1192 = 1192 * y; int r = (y1192 + 1634 * v); int g = (y1192 - 833 * v - 400 * u); int b = (y1192 + 2066 * u); if (r < 0) r = 0; else if (r > 262143) r = 262143; if (g < 0) g = 0; else if (g > 262143) g = 262143; if (b < 0) b = 0; else if (b > 262143) b = 262143; // rgb[yp] = 0xff000000 | ((r << 6) & 0xff0000) | ((g >> 2) & // 0xff00) | ((b >> 10) & 0xff); // rgba, divide 2^10 ( >> 10) rgba[yp] = ((r << 14) & 0xff000000) | ((g << 6) & 0xff0000) | ((b >> 2) | 0xff00); } } }