Android怎么实现边采集边上传

 我来答
greystar_cn
2016-08-03 · 知道合伙人软件行家
greystar_cn
知道合伙人软件行家
采纳数:16407 获赞数:17260
本人主要从事.NET C#方向的技术开发工作,具有10多年的各类架构开发工作经验。

向TA提问 私信TA
展开全部
最近看了Sipdroid和ZXing两个开源代码,对于如何在Andrpid平台上实现边采集边上传的功能有了新的见解,同时也决定重新弄一下以前做的广州亚运排传的项目.

先给大家说下软件的功能吧.

拿出android手机然后采集实时的图片数据,并对这些采集的图片数据进行H264编码,然后根据协议上传到公司的服务器上。

那么现在大家分析下,如果要实现这些功能,有哪些技术瓶颈:

1.Camera参数设置,设置不正确,无法看到视频,而且最主要的是有的时候你用的设置在公司的测试机上运行正常在其他手机上就看不到视频了。

2.如何获取采集的实时图片数据

3.摄像头打开后大家发现没图片是倒置的,原因何在,如何解决倒置的问题呢?

4.H264压缩编码

5.H264编码后的图片显示为灰白色的,为什么呢?

请看我下面的代码,我将为大家详细的解释上面的情况出现的理由和解决方案:

package com.camera.CameraPreview;

import java.io.IOException;

import android.app.Activity;

import android.content.pm.ActivityInfo;

import android.hardware.Camera;

import android.hardware.Camera.PreviewCallback;

import android.os.Bundle;

import android.view.SurfaceHolder;

import android.view.Window;

import android.view.SurfaceHolder.Callback;

import android.view.SurfaceView;

public class PreviewActivity extends Activity implements Callback, PreviewCallback {

private SurfaceView mSurface ;

private SurfaceHolder mHolder;

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

requestWindowFeature(Window.FEATURE_NO_TITLE);

//and set the preview to landscape mode.

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

setContentView(R.layout.main);

mSurface = (SurfaceView)this.findViewById(R.id.SurfacePrewView);

mHolder = mSurface.getHolder();

mHolder.addCallback(this);

mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);//该代码放在addCallback前还是addCallback后对代码Camera有没有影响

}

@Override

public void surfaceChanged(SurfaceHolder holder, int format, int width,

int height) {

Camera.Parameters parame = mCamera.getParameters();

parame.setPreviewSize(320,480);

mCamera.startPreview();

}

private Camera mCamera ;

@Override

public void surfaceCreated(SurfaceHolder holder) {

if(mCamera!=null)

{

mCamera.release();

mCamera = null ;

}

//<uses-permission android:name="android.permission.CAMERA" />

//必须添加此权限,否则DDMS便会提示你:can not connect to Camera service

mCamera = Camera.open();

try {

mCamera.setPreviewDisplay(mHolder);//此代码必须添加视频才会显示出来

mCamera.setPreviewCallback(this);

} catch (IOException e) {

e.printStackTrace();

}

}

@Override

public void surfaceDestroyed(SurfaceHolder holder) {

if(mCamera != null)

{

mCamera.release();

mCamera = null ;

}

}

@Override

public void onPreviewFrame(byte[] data, Camera camera) {

// TODO Auto-generated method stub

//get the prew frame here,the data of default is YUV420_SP

//you should change YUV420_SP to YUV420_P

}

}
复制代码

1. 为了确保在所有的平台上你都能够看到画面,SurfaceCreated() SurfaceChanged() SurfaceDestory()请一定要按照上面的写法写:
SurfaceCreated中注意
mCamera.setPreviewDisplay(mHolder);//此代码必须添加视频才会显示出来
mCamera.setPreviewCallback(this);//设置预览帧的接口,就是通过这个接口,我们来获得预览帧的数据的

2.图像是倒的如何解决?
//and set the preview to landscape mode.
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
在SetContentView之前调用此代码,理由大家自己看API文档,解释的麻烦.

3.public void onPreviewFrame(byte[] data, Camera camera)

该接口为获取视频预览帧的接口,传递进来的data,默认是YUV420SP的,H264编码的源默认是YUV420的,将他们转换一下再编码图像就正常了;

转换函数:

private byte[] changeYUV420SP2P(byte[]data,int length){

int width = 176;

int height = 144;

byte[] str = new byte[length];

System.arraycopy(data, 0, str, 0,width*height);

int strIndex = width*height;

for(int i = width*height+1; i < length ;i+=2)

{

str[strIndex++] = data[i];

}

for(int i = width*height;i<length;i+=2)

{

str[strIndex++] = data[i];

}

return str;

}
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式