在 Android 中显示 YUV 图像 [英] Displaying YUV Image in Android

查看:21
本文介绍了在 Android 中显示 YUV 图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的应用程序中,我们需要显示从服务器接收到的视频帧到我们的 android 应用程序,
服务器正在以每秒 50 帧的速度发送视频数据,已在 WebM 中编码,即使用 libvpx 对图像进行编码和解码,

In my application, we need to display the Video frame receives from server to our android application,
Server is sending video data @ 50 frame per second, having encoded in WebM i.e. using libvpx to encode and decode the images,

现在从 libvpx 解码后,它得到 YUV 数据,我们可以显示在图像布局上,

Now after decoding from libvpx its getting YUV data, that we can displayed over the image layout,

目前的实现是这样的,

在 JNI/Native C++ 代码中,我们将 YUV 数据转换为 RGB 数据在Android框架中,调用

In JNI / Native C++ code, we are converting YUV data to RGB Data In Android framework, calling

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

要创建位图图像,

使用以下代码在 imageView 上显示图像,

to display the image over imageView using following code,

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

我的查询是,总体而言,此功能大约需要 40 毫秒,有什么方法可以优化它,
1 - 有没有办法将 YUV 数据显示到 imageView ?

My query is, overall this function is taking approx 40 ms, is there any way to optimize it,
1 -- Is there any way to display YUV data to imageView ?

2 -- 有没有其他方法可以从 RGB 数据创建图像(位图图像​​),

2 -- Is there any other way to create Image( Bitmap image) from RGB data ,

3 -- 我相信我总是在创建图像,但我想我应该只创建一次位图,并且总是在我们收到时执行/提供新缓冲区.
请分享你的观点.

3 -- I believe i am always creating image, but i suppose i should create bitmap only once and do / supply new buffer always, as and when we received.
please share your views.

推荐答案

以下代码解决了你的问题,由于YuvImage类是Android-SDK提供的,所以Yuv格式数据可能需要更少的时间.

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

你可以试试这个,

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

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

这篇关于在 Android 中显示 YUV 图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆