`
cwh643
  • 浏览: 127540 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
文章分类
社区版块
存档分类
最新评论

Android拍摄视频流的格式转换(YUV --- RGB)

阅读更多
Android允许用户实时捕获摄像头的视频流,这在利用摄像头的AR应用中非常有用。可以利用摄像流实时做画面图像的分析,并做出许多有用的应用。比如人脸识别,条码识别,特定图像替换等等,不过大多数图像处理软件在处理时是需要RGB格式的图像,而默认的视频流是压缩的YUV格式,Android下是YUV420SP,这个格式,虽然可以在程序中修改,但是修改后好像不起作用,也就是说只能得到编码为YUV420SP的视频流,这就需要把YUV420SP的视频流转换成RGB格式的图像,用于图像识别。特贴一个格式转换函数,方便大家使用。
    static public void decodeYUV420SP(byte[] rgbBuf, byte[] yuv420sp, int width, int height) {
    	final int frameSize = width * height;
		if (rgbBuf == null)
			throw new NullPointerException("buffer 'rgbBuf' is null");
		if (rgbBuf.length < frameSize * 3)
			throw new IllegalArgumentException("buffer 'rgbBuf' size "
					+ rgbBuf.length + " < minimum " + frameSize * 3);

		if (yuv420sp == null)
			throw new NullPointerException("buffer 'yuv420sp' is null");

		if (yuv420sp.length < frameSize * 3 / 2)
			throw new IllegalArgumentException("buffer 'yuv420sp' size " + yuv420sp.length
					+ " < minimum " + frameSize * 3 / 2);
    	
    	int i = 0, y = 0;
    	int uvp = 0, u = 0, v = 0;
    	int y1192 = 0, r = 0, g = 0, b = 0;
    	
    	for (int j = 0, yp = 0; j < height; j++) {
    		uvp = frameSize + (j >> 1) * width;
    		u = 0;
    		v = 0;
    		for (i = 0; i < width; i++, yp++) {
    			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;
    			}
    			
    			y1192 = 1192 * y;
    			r = (y1192 + 1634 * v);
    			g = (y1192 - 833 * v - 400 * u);
    			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;
    			
    			rgbBuf[yp * 3] = (byte)(r >> 10);
    			rgbBuf[yp * 3 + 1] = (byte)(g >> 10);
    			rgbBuf[yp * 3 + 2] = (byte)(b >> 10);
    		}
    	}
    }

分享到:
评论
18 楼 lsll_android 2013-07-18  
v = (0xff & yuv420sp[uvp++]) - 128;//抛java.lang.arrayindexoutofboundsexception异常
17 楼 ihopethatwell 2012-07-18  
楼主,附上完整的demo吧,看着回复,好花
16 楼 cwh643 2012-03-27  
Jefry 写道
大侠,ARGB_8888占4个字节啊,怎么乘以3呢

这个函数是转成RGB的,如果要ARGB,请按照下面提示自行修改
out[yp] = 0xff000000 | ((r << 6) & 0xff0000) | ((g >> 2) & 0xff00) | ((b >> 10) & 0xff);
15 楼 土块的魅力 2012-02-17  
我的在pc机端是花屏,如果解决的话请指点,qq:776704371,谢谢了!
14 楼 Jefry 2012-02-03  
大侠,ARGB_8888占4个字节啊,怎么乘以3呢
13 楼 windloverain 2011-06-17  
very good.
学习下。
12 楼 zhjb_javaeye 2011-05-20  
cwh643 写道
keithlee980 写道
楼主,请问这个函数怎么使用呢?是不是在onPreviewFrame里调用?我调用了转换出的图片打不开,应该是我没调用好。麻烦楼主讲一下怎么调用这个函数吧。谢谢了。

我是这样调用的,你可以参考一下
    	public synchronized void onPreviewFrame(byte[] data, Camera camera) {
    		if (data == null) {
    			return;
    		}
    		if (isStopPreview) {
    			return;
    		}
    		if (mRenderer == null) {
    			return;
    		}
    		//关闭摄像头预览回调
    		camera.setPreviewCallback(null);
    		
    		if (bitmapData == null) {
    			previewWidth = camera.getParameters().getPreviewSize().width;
        		previewHeight = camera.getParameters().getPreviewSize().height;
        		bitmapData = new int[previewWidth * previewHeight];
        		rgbBuffer = new byte[previewWidth * previewHeight * 3];
    		}
    		
			decodeYUV420SP(bitmapData, rgbBuffer, data, previewWidth, previewHeight);
			
			if (mARHelp != null) {
				//调用artoolkit识别
				mARHelp.findMarker(rgbBuffer, mRenderer);
			}
			//取得摄像头画面
			Bitmap image = Bitmap.createBitmap(bitmapData, previewWidth, previewHeight, Bitmap.Config.ARGB_8888);
			mRenderer.setBackgroundImage(image);
			
			//刷新openGL显示
			requestRender();
			
			//打开摄像头预览回调
			camera.setPreviewCallback(this);
    	}


楼主,能你发的“decodeYUV420SP”少了个参数,能否帖个这断代码里用的“decodeYUV420SP”方法不???
11 楼 cwh643 2011-01-07  
lipeng88213 写道
cwh643 写道
lipeng88213 写道
jasonchain 写道
我怎么转出来是花的?

楼上的问题解决了吗 我的也是花的

请教楼主 花屏如何解决啊。。。。

我这里一直用的,在多款android手机上测试都是好的,包括最新的Nexus s,只是在模拟器上有一些阴影一样的颜色,不知道你们的程序是否有其他问题

我调了一下 感觉是
byte[] rgbBuf, byte[] yuv420sp, int width, int height
这几个参数的比例 应该有某种问题

不知道 楼主 是怎么设置的 以及 android端setPreviewSize的大小

我的程序中是这样设置这些参数的
previewWidth = camera.getParameters().getPreviewSize().width;
previewHeight = camera.getParameters().getPreviewSize().height;
rgbBuffer = new byte[previewWidth * previewHeight * 3];
decodeYUV420SP(rgbBuffer, data, previewWidth, previewHeight);

就是说这里PreviewSize是取得当前camera的实际的PreviewSize,你设定的previewSize不一定是设备的可以支持的
10 楼 lipeng88213 2010-12-08  
cwh643 写道
lipeng88213 写道
jasonchain 写道
我怎么转出来是花的?

楼上的问题解决了吗 我的也是花的

请教楼主 花屏如何解决啊。。。。

我这里一直用的,在多款android手机上测试都是好的,包括最新的Nexus s,只是在模拟器上有一些阴影一样的颜色,不知道你们的程序是否有其他问题

我调了一下 感觉是
byte[] rgbBuf, byte[] yuv420sp, int width, int height
这几个参数的比例 应该有某种问题

不知道 楼主 是怎么设置的 以及 android端setPreviewSize的大小
9 楼 cwh643 2010-12-08  
lipeng88213 写道
jasonchain 写道
我怎么转出来是花的?

楼上的问题解决了吗 我的也是花的

请教楼主 花屏如何解决啊。。。。

我这里一直用的,在多款android手机上测试都是好的,包括最新的Nexus s,只是在模拟器上有一些阴影一样的颜色,不知道你们的程序是否有其他问题
8 楼 lipeng88213 2010-12-07  
jasonchain 写道
我怎么转出来是花的?

楼上的问题解决了吗 我的也是花的

请教楼主 花屏如何解决啊。。。。
7 楼 cwh643 2010-10-08  
jasonchain 写道
cwh643 写道

有点绿色,蓝色

很遗憾,你的问题还没有解决,我想你可能还没有理解rgbBuf到bitmap的转换,中间可能有些颜色产生了互相影响,你看这个方法是否可以帮助你,吧你个方法的最后几行改成这样 rgbBuf[yp * 3] = (byte)(r >> 10);
rgbBuf[yp * 3 + 1] = (byte)(g >> 10);
rgbBuf[yp * 3 + 2] = (byte)(b >> 10);

out[yp] = 0xff000000 | ((r << 6) & 0xff0000) | ((g >> 2) & 0xff00) | ((b >> 10) & 0xff);

这里就是把原来的rgbbuffer,转成用于生成bitmap的buffer,格式是ARGB
jasonchain 写道
jasonchain 写道
我怎么转出来是花的?



谢谢您的回复,已经试过了,效果一样

你在真机上试了吗,应该可以的,如果效果不好,是不是由于图片的PreviewSize像素设的太低了呢?
6 楼 cwh643 2010-10-08  
keithlee980 写道
楼主,请问这个函数怎么使用呢?是不是在onPreviewFrame里调用?我调用了转换出的图片打不开,应该是我没调用好。麻烦楼主讲一下怎么调用这个函数吧。谢谢了。

我是这样调用的,你可以参考一下
    	public synchronized void onPreviewFrame(byte[] data, Camera camera) {
    		if (data == null) {
    			return;
    		}
    		if (isStopPreview) {
    			return;
    		}
    		if (mRenderer == null) {
    			return;
    		}
    		//关闭摄像头预览回调
    		camera.setPreviewCallback(null);
    		
    		if (bitmapData == null) {
    			previewWidth = camera.getParameters().getPreviewSize().width;
        		previewHeight = camera.getParameters().getPreviewSize().height;
        		bitmapData = new int[previewWidth * previewHeight];
        		rgbBuffer = new byte[previewWidth * previewHeight * 3];
    		}
    		
			decodeYUV420SP(bitmapData, rgbBuffer, data, previewWidth, previewHeight);
			
			if (mARHelp != null) {
				//调用artoolkit识别
				mARHelp.findMarker(rgbBuffer, mRenderer);
			}
			//取得摄像头画面
			Bitmap image = Bitmap.createBitmap(bitmapData, previewWidth, previewHeight, Bitmap.Config.ARGB_8888);
			mRenderer.setBackgroundImage(image);
			
			//刷新openGL显示
			requestRender();
			
			//打开摄像头预览回调
			camera.setPreviewCallback(this);
    	}
5 楼 jasonchain 2010-09-28  
cwh643 写道

有点绿色,蓝色

很遗憾,你的问题还没有解决,我想你可能还没有理解rgbBuf到bitmap的转换,中间可能有些颜色产生了互相影响,你看这个方法是否可以帮助你,吧你个方法的最后几行改成这样 rgbBuf[yp * 3] = (byte)(r >> 10);
rgbBuf[yp * 3 + 1] = (byte)(g >> 10);
rgbBuf[yp * 3 + 2] = (byte)(b >> 10);

out[yp] = 0xff000000 | ((r << 6) & 0xff0000) | ((g >> 2) & 0xff00) | ((b >> 10) & 0xff);

这里就是把原来的rgbbuffer,转成用于生成bitmap的buffer,格式是ARGB
jasonchain 写道
jasonchain 写道
我怎么转出来是花的?



谢谢您的回复,已经试过了,效果一样
4 楼 keithlee980 2010-09-27  
楼主,请问这个函数怎么使用呢?是不是在onPreviewFrame里调用?我调用了转换出的图片打不开,应该是我没调用好。麻烦楼主讲一下怎么调用这个函数吧。谢谢了。
3 楼 cwh643 2010-09-27  

有点绿色,蓝色

很遗憾,你的问题还没有解决,我想你可能还没有理解rgbBuf到bitmap的转换,中间可能有些颜色产生了互相影响,你看这个方法是否可以帮助你,吧你个方法的最后几行改成这样 rgbBuf[yp * 3] = (byte)(r >> 10);
rgbBuf[yp * 3 + 1] = (byte)(g >> 10);
rgbBuf[yp * 3 + 2] = (byte)(b >> 10);

out[yp] = 0xff000000 | ((r << 6) & 0xff0000) | ((g >> 2) & 0xff00) | ((b >> 10) & 0xff);

这里就是把原来的rgbbuffer,转成用于生成bitmap的buffer,格式是ARGB
jasonchain 写道
jasonchain 写道
我怎么转出来是花的?
2 楼 jasonchain 2010-08-20  
jasonchain 写道
我怎么转出来是花的?

有点绿色,蓝色
1 楼 jasonchain 2010-08-20  
我怎么转出来是花的?

相关推荐

    RGB-YUV转换工具 - Android App

    RGB-YUV转换工具是一款专为Android平台设计的应用程序,它主要功能是实现RGB色彩空间与YUV色彩空间之间的转换。在数字图像处理和视频编码领域,YUV色彩模型被广泛使用,因为它能有效地减少存储和传输的数据量,尤其...

    opengl es2.0 -YUV-RGB互转+显示到手机屏幕 DEMO

    此外,你还需要熟悉YUV的不同存储格式和它们与RGB转换的数学公式。 在实际应用中,为了提高性能,你可能会考虑使用硬件加速的YUV解码器或者利用硬件提供的YUV到RGB转换功能,这通常取决于具体设备的支持。同时,...

    PLDroidDemo,Yuv--&gt;H264,Yuv--&gt;RGB,GL模糊,GPuimage.zip

    【PLDroidDemo】是一个开源项目,主要涉及Android平台上的视频处理技术,特别是与YUV到H264、YUV到RGB转换以及图形处理相关的功能。该项目为开发者提供了丰富的工具和示例代码,帮助他们理解和实现这些高级图像处理...

    YUVUtilsDemo:YUV-Android工具包

    `YUVUtilsDemo`是一个针对Android平台的YUV处理工具包,旨在帮助开发者更方便地操作和转换YUV数据。这个工具包的依赖是`libyuv-android`,版本为1.0.0,由`cwpf.yuvutils`提供。 YUV,全称为“亮度(Y)+两个色差...

    android yuv420sp叠加osd

    2. **YUV到RGB转换**: 使用`YUV420ToARGB8888`函数将YUV数据转换为RGB格式,以便在Android的Canvas上操作。 3. **绘制OSD信息**: 在转换后的RGB Bitmap上使用`Canvas`对象绘制文本、图形等OSD信息。这可能包括时间戳...

    OpenGL如何处理YUV数据(Android开发)(格式:I420、NV12、NV21)

    - **着色器编程**:编写和使用GLSL着色器,转换YUV数据为RGB。 - **绘制调用**:执行绘制命令,将YUV数据渲染到屏幕。 **3. I420到RGB转换** 对于I420格式,由于Y、U、V分量的分辨率不同,需要分别处理。通常先将Y...

    yuv420转rgb

    海康威视sdk中,将视频流转换为图像,并可以将图像转换为视频流的方法。

    android 显示yuv图片

    3. **颜色转换**:由于Android默认使用RGB格式进行显示,所以需要将YUV数据转换为RGB。可以使用`Android硬件加速器`(如`renderscript`或`OpenGL ES`)或者手动实现转换算法。 4. **创建Bitmap**:将转换后的RGB数据...

    Android OpenGLES2.0相关代码 包括一个yuv、RGB互转并显示图片demo 共两个资源

    在Android设备上,显示视频通常需要将YUV数据转换成RGB格式。 要实现YUV到RGB的转换,我们可以编写一个OpenGL ES 2.0的顶点着色器和片段着色器。顶点着色器负责处理几何形状的位置,而片段着色器则负责处理像素颜色...

    YUVRender:该项目使用GPU将YUV转换为RGB,以便在Android平台上进行渲染

    在Android平台上,图像处理是一个常见的需求,特别是在视频流媒体、实时滤镜以及摄像头应用中。`YUVRender`项目正是针对这一需求而设计的,它利用GPU的强大计算能力,将YUV格式的图像数据高效地转换成RGB格式,以...

    yuv to rgb color convert

    通过学习和理解这个教程,开发者可以掌握将YUV视频数据转换为RGB像素流,并在Android设备上进行显示的核心技术。这对于开发涉及视频处理和播放的应用至关重要,能够提高用户体验并节省系统资源。

    YUV和NV12T转RGB

    本文将详细讨论“YUV”和“NV12T”这两种颜色空间转换为“RGB”的过程,以及如何在Linux和Android平台上实现这种转换。 首先,我们需要理解YUV和NV12T颜色空间。YUV是一种广泛用于视频编码的颜色模型,它将颜色信息...

    NDK开发——FFmpeg实现视频转YUV、视频转RGB显示、音频转PCM、音频播放、音视频同步

    在实际应用中,通常会编写一个媒体播放器框架,该框架包括初始化FFmpeg,加载媒体文件,解码音频和视频流,进行色彩空间和格式转换,同步音视频,以及播放控制等功能。在Android的NDK环境中,需要特别关注内存管理,...

    libyuv安卓Android 编译好SO库文件及源代码

    libyuv是一个开源项目,专门用于视频帧的色彩空间转换,它提供了一种高效的方法来处理YUV到RGB以及其他格式之间的转换。在Android平台上,libyuv被广泛应用于多媒体处理,尤其是在处理视频流时,由于其高度优化的...

    android usb摄像头 支持yuyv mjpeg格式

    处理YUYV格式时,需要按照特定的顺序读取和解析像素数据,将其转换为RGB格式供显示。 2. MJPEG(Motion JPEG)格式:MJPEG是一种将连续的JPEG图像帧封装成视频流的格式。每个帧都是一个独立的JPEG图像,通过时间上...

    libyuv-android-master

    3. **YUV与RGB转换**:在Android系统中,大部分图形操作都基于RGB色彩空间,因此,libyuv-android提供了高效且精确的YUV到RGB和RGB到YUV的转换算法,确保在不同色彩空间间转换的准确性和效率。 三、libyuv-android...

    android下v4l2拍摄jpg格式图片

    在Android平台上,开发一款应用程序来使用Video for Linux Two (V4L2)接口捕获YUV数据,并通过移植libjpeg库将其转换为JPEG格式的图片,是一项技术挑战。以下是对这个过程的详细解释: 首先,V4L2是Linux内核提供的...

    android FFmpeg视频解码为YUV像素数据视频文件以及获取视频基本参数信息

    解码后的AVFrame包含了视频帧的数据,可以是YUV、RGB等格式。 2. **新API**:在新API中,解码过程变得更加异步。`avcodec_send_packet`将编码数据包送入解码器,然后`avcodec_receive_frame`会在解码完成时返回解码...

    ffmpeg视频解码成YUV,JPG

    FFmpeg是一款强大的开源多媒体处理工具,它包含了音视频编解码、封装、转换、流媒体等功能。在这个场景中,我们主要关注的是如何使用FFmpeg将视频解码为YUV格式,以及将YUV数据转化为JPEG图片。下面我们将详细介绍这...

    Android视频采集+RTSP完整代码(可用)

    - **处理预览数据**:可能涉及到YUV到RGB的转换,以便在SurfaceView上显示。 - **MediaRecorder配置**:设置视频编码(如H.264)、音频编码(如AAC)、比特率、分辨率、帧率等。 - **建立RTSP连接**:创建RTSP...

Global site tag (gtag.js) - Google Analytics