如标题所述,学习如何打开摄像头,并在屏幕上预览图像。使用Camera的步骤:
(1)调用Camera的open()方法打开相机;
(2)调用Camera的getParameters()方法获取拍照参数,该方法返回一个Camera.Parameters对象;
(3)调用Camera的setParameters()方法//android2.3.3以后无需此步;
(4)调用Camera的startPreview()方法开始预览取景,在预览取景之前需要调用Camera的setPreviewDisplay(SurfaceHolder holder)方法设置使用哪个surfaceview来显示取景图片;
(5)结束程序时,调用Camera的stopPreview()结束取景预览,并调用release()方法释放资源。
以上过程参考《疯狂android讲义》,这本书确实不错,能够快速入门。整个系统大部分框架是参考此书的,部分问题在网上搜的资料。
1.在AndroidManifest.xml文件中添加camera的权限
<!-- 授予程序使用摄像头的权限 -->
<uses-permission android:name=
"android.permission.CAMERA"
/>
<uses-feature android:name=
"android.hardware.camera"
/>
<uses-feature android:name=
"android.hardware.camera.autofocus"
/>
|
2.在界面布局文件中添加一个surfaceview用于显示预览图片
<SurfaceView
android:id=
"@+id/sView"
android:layout_width=
"fill_parent"
android:layout_height=
"fill_parent"
/>
|
3.程序主体
在这里我们定义了一个SurfaceView变量sView用于获取布局文件中定义的SurfaceView组件。关于SurfaceView的基本问题,论坛上http://www.apkbus.com/android-43293-1-1.html这个帖子讲的蛮好的。
我们在SurfaceView被创建时调用initcamera()初始化摄像头,在SurfaceView被销毁时释放摄像头。而这两个时间是通过surfaceHolder.addCallback得到的,看看下面代码就明白了。
public
class
MainActivity
extends
Activity {
SurfaceView sView;
SurfaceHolder surfaceHolder;
int
screenWidth, screenHeight;
// 定义系统所用的照相机
Camera camera;
//是否在浏览中
boolean
isPreview =
false
;
@Override
public
void
onCreate(Bundle savedInstanceState)
{
super
.onCreate(savedInstanceState);
// 设置全屏
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_main);
WindowManager wm = (WindowManager) getSystemService(
Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
// 获取屏幕的宽和高
screenWidth = display.getWidth();
screenHeight = display.getHeight();
// 获取界面中SurfaceView组件
sView = (SurfaceView) findViewById(R.id.sView);
// 获得SurfaceView的SurfaceHolder
surfaceHolder = sView.getHolder();
// 为surfaceHolder添加一个回调监听器
surfaceHolder.addCallback(
new
Callback()
{
@Override
public
void
surfaceChanged(SurfaceHolder holder,
int
format,
int
width,
int
height)
{
}
@Override
public
void
surfaceCreated(SurfaceHolder holder)
{
// 打开摄像头
initCamera();
}
@Override
public
void
surfaceDestroyed(SurfaceHolder holder)
{
// 如果camera不为null ,释放摄像头
if
(camera !=
null
)
{
if
(isPreview)
camera.stopPreview();
camera.release();
camera =
null
;
}
}
});
// 设置该SurfaceView自己不维护缓冲
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
private
void
initCamera()
{
if
(!isPreview)
{
camera = Camera.open();
}
if
(camera !=
null
&& !isPreview)
{
try
{
Camera.Parameters parameters = camera.getParameters();
// 设置预览照片的大小
parameters.setPreviewSize(screenWidth, screenHeight);
// 每秒显示4帧
parameters.setPreviewFrameRate(
4
);
// 设置图片格式
parameters.setPictureFormat(PixelFormat.JPEG);
// 设置JPG照片的质量
parameters.set(
"jpeg-quality"
,
85
);
//设置照片的大小
parameters.setPictureSize(screenWidth, screenHeight);
//android2.3.3以后无需下步
//camera.setParameters(parameters);
//通过SurfaceView显示取景画面
camera.setPreviewDisplay(surfaceHolder);
// 开始预览
camera.startPreview();
// 自动对焦
camera.autoFocus(
null
);
}
catch
(Exception e)
{
e.printStackTrace();
}
isPreview =
true
;
}
}
}
|
就这样你就可以使用摄像头预览了。当然你会发现预览的图像转了90度,方向不对。我们在AndroidManifest.xml文件的activity属性设置中添加
android:screenOrientation=
"landscape"
|
设置成横屏就OK了。如果黑屏请检查camera.setParameters(parameters);这步是否与自己系统匹配,2.3.3以后是不须此步的。
就这样简单,我们就完成了无线视频监控的第一步,实现了摄像头图像的预览。在这里我们设置了预览但是却没有对每帧图像数据进行处理,下次将讲如何获得摄像头的每一帧图像以及如何处理。