Camera的回调函数onPreviewFrame

windfury_plus 2014-11-18 03:11:54
public void onPreviewFrame(byte[] data, Camera camera)
data是回调函数的视频数据。现在的问题是虽然可以用setDisplayOrientation方法改变预览界面。
但是你无法改变回调函数里的data

网上搜过一段时间,基本上能给出的解决方案都是setDisplayOrientation或者android:screenOrientation="portrait"……
总之没用。
在http://stackoverflow.com暂时搜到一个,方法和我想的一样——先生成bitmap,转换bitmap的方向后再转回byte流
不过这个效率很低,而目前项目中使用是需要实时的视频数据,所以不久手机应用就崩了。

现在有大神研究出解决方案了么?希望赐教,不胜感激~

...全文
2965 8 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
yaerfeng 2015-12-28
  • 打赏
  • 举报
回复
引用 6 楼 inquisitive_plus 的回复:
结贴,最后在上午结束前完成了转换。不过也发现了程序设计上的不足。 总之解决思路就是前面所说的了。先对Y进行排列,在对UV进行排列,不同的编码格式的差异在于UV。 项目中用的是YV12的转换算法。排列是U在前V在后,而I420是V在前U在后,所占位子一样。 NV21除了Y是一样的,UV是排列在一起的。 百度一下有很多资料。 我并不觉得这是最优解,不过基于没有找到资料,只能说出这些了。希望日后有大神看到这个帖子后,多写优秀的文章分享大家,如同《超体》所提到:生命的意义就在于知识的传递。
方便留下联系方式么。邮件也行。求onPreviewFrame这块的处理方式。
yaerfeng 2015-12-28
  • 打赏
  • 举报
回复
方便留下联系方式么。邮件也行。求onPreviewFrame这块的处理方式。
windfury_plus 2014-11-20
  • 打赏
  • 举报
回复
看来没大神帮忙,我说下我的进度。 目前使用stackoverflow提供的方法,转为jpeg时,哪怕质量设置为100,获得的数据流依然比之前的小。损失很大。 而使用对视频流流Byte数组直接变换方向,则有了初步效果。 android预览的效果默认为NV21和yv12(华为G750-T00),在目前的项目中使用算法转换后,再通知下层长和宽对调了。 得到的结果是:图像方向算是正确,还需要做一次镜像处理。不过颜色没了,估计是YUV算法里,UV没调整对。还有待改进。 希望有研究的人可以分享下自己的结果。
windfury_plus 2014-11-20
  • 打赏
  • 举报
回复
结贴,最后在上午结束前完成了转换。不过也发现了程序设计上的不足。 总之解决思路就是前面所说的了。先对Y进行排列,在对UV进行排列,不同的编码格式的差异在于UV。 项目中用的是YV12的转换算法。排列是U在前V在后,而I420是V在前U在后,所占位子一样。 NV21除了Y是一样的,UV是排列在一起的。 百度一下有很多资料。 我并不觉得这是最优解,不过基于没有找到资料,只能说出这些了。希望日后有大神看到这个帖子后,多写优秀的文章分享大家,如同《超体》所提到:生命的意义就在于知识的传递。
windfury_plus 2014-11-19
  • 打赏
  • 举报
回复
引用 3 楼 youngc527 的回复:
stackoverflow上面看到过一段nv21旋转90度的算法,链接忘了,自己搜搜看吧
是这个么?http://stackoverflow.com/questions/15131663/how-to-change-orientation-of-captured-byte-frames-through-onpreviewframe-callb 我也套用了……

if (data.length != 0)
{
	previewSize = camera.getParameters().getPreviewSize();//后面用于获取长、宽
	 yuv = new YuvImage(data, ImageFormat.NV21,previewSize.width, previewSize.height, null);
						
       LogUtil.i("previewSize", previewSize.width+"            "+previewSize.height);
       // Decode image from the retrieved buffer to JPEG
      yuv = new YuvImage(data, ImageFormat.NV21,previewSize.width, previewSize.height, null);
      yuv.compressToJpeg(new Rect(0, 0,previewSize.width, previewSize.height),100, baos);

      rawImage = baos.toByteArray();
      // This is the same image as the preview but in JPEG
      // and not rotated					
       bitmap = BitmapFactory.decodeByteArray(rawImage, 0, rawImage.length);

  	// We rotate the same Bitmap
	// 旋转
	matrix.postRotate(90);
	bitmap = Bitmap.createBitmap(bitmap, 0, 0,previewSize.width, previewSize.height,matrix, false);

       // We dump the rotated Bitmap to the stream
      bitmap.compress(CompressFormat.JPEG,100, rotatedStream);
      rawImage = rotatedStream.toByteArray();
     // rawImage就是最后要用的视频流了			
     
代码如上。我运行后发现,rawImage的大小比原本data[]大,还有增加的趋势。应该是哪里写错了…… 这里没声明的变量都是全局的。rawImage 要清空么? 能否帮忙看下,谢谢~
Darcy杨 2014-11-19
  • 打赏
  • 举报
回复
stackoverflow上面看到过一段nv21旋转90度的算法,链接忘了,自己搜搜看吧
windfury_plus 2014-11-19
  • 打赏
  • 举报
回复
引用 1 楼 YKDSea 的回复:
camera的display orientation大多数情况下的确是不改变数据,只是改变了display的那个surface的方向。最好描述一下你要怎么使用这个数据的,看看有没有其他方法来做。
要把传输的data[]经过服务器显示在pc客户端上。这个都是成功的,只是以前手机是横屏的,传的数据是没问题的。而现在项目里暂时改成竖屏,所以就转了90度。 想法很单纯,就是把data[]的转个角度就可以了。也不建议在pc上改了。能否有个算法吧data[]转向,因为data[]是每一帧的数据,所以理所当然应该也是个图片,编码是NV21。
sky-Z 2014-11-18
  • 打赏
  • 举报
回复
camera的display orientation大多数情况下的确是不改变数据,只是改变了display的那个surface的方向。最好描述一下你要怎么使用这个数据的,看看有没有其他方法来做。

80,472

社区成员

发帖
与我相关
我的任务
社区描述
移动平台 Android
androidandroid-studioandroidx 技术论坛(原bbs)
社区管理员
  • Android
  • yechaoa
  • 失落夏天
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧