Displaying Yuv Image in Android

Displaying YUV Image in Android

Following code solve your problem and it may take less time on Yuv Format data because YuvImage class is provided with Android-SDK.

You can try this,

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);

or

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);
}
}
}

Play yuv frames in Android

Whilst JPEG encoding and decoding may be hardware accelerated on most phones, I would expect a simple RGB->YUV conversion for-loop you wrote yourself to be much faster (fast enough even in Java without using a native library) and simpler.

Here is the formula. If you are using OpenGLES to display, consider using a fragment shader to do the conversion on-the-fly.

Finally, here's the integer-only code you can use on the CPU:

Ytmp =      4768 * (Y - 16);
R = (Ytmp + 6537 * (V - 128)) >> 12;
G = (Ytmp - 3330 * (V - 128) - 1602 * (U - 128)) >> 12;
B = (Ytmp + 8266 * (U - 128)) >> 12;

How can I create a YuvImage in android

You can get your desired Parameter (data) by Converting the resource Drawable to Bytearray then use it to get the YUV image :

Resources res = getResources();
Drawable drawable = res.getDrawable(R.drawable.my_pic);
Bitmap bitmap = ((BitmapDrawable)drawable).getBitmap();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
byte[] bitMapData = stream.toByteArray();

Converting YUV-RGB(Image processing)-YUV during onPreviewFrame in android?

Why not specify that camera preview should provide RGB images?

i.e. Camera.Parameters.setPreviewFormat(ImageFormat.RGB_565);

Rendering YUV format in android?

Yes and no.

The output of the camera and hardware video decoders is generally YUV. Frames from these sources are generally sent directly to the display. They may be converted by the driver, typically with a hardware scaler and format converter. This is necessary for efficiency.

There isn't an API to allow an app to pass YUV frames around the same way. The basic problem is that "YUV" covers a lot of ground. The buffer format used by the video decoder may be a proprietary internal format that the various hardware modules can process efficiently; for your app to create a surface in this format, it would have to perform a conversion, and you're right back where you were performance-wise.

You should be able to use GLES2 shaders to do the conversion for you on the way to the display, but I don't have a pointer to code that demonstrates this.

Update: an answer to this question has a link to a WebRTC source file that demonstrates doing the YUV conversion in a GLES2 shader.



Related Topics



Leave a reply



Submit