您的位置:首页 > 移动开发 > Android开发

Android之Camera的简单实例

2015-07-22 12:54 483 查看
好久没写博客了。。。嗯,主要还是期末复习(突击,大家都懂得~



然后也没学什么,就没写了。。。

考试考完了,暑假期间当然不能什么都不干,对吧?

所以,就决定借这个暑假时间,对于Android项目练练手。。。

这次,主要做一个跟手机Camera有关的一个小型APP~

先来简单介绍一下Android中Camera类~

Camera类是包含在android.hardware包中的一个类,该类主要用于对摄像头的控制。

它的常用方法有如下几个:

void autoFocus(Camera,AutoFocusCallback cb) ------ 设置自动对焦
Camera.Parameters.getParameters() ------ 得到相机参数

Camera open() ------ 启动相机服务

void release() ------ 释放相机服务

void setParameters(Camera.Parameters params) ------ 设置相机参数

void setPreviewDisplay(SurfaceHolder holder) ------ 设置预览

void startPreview() ------ 开始预览

void stopPreview() ------ 停止预览

void takePicture(Camera.ShutterCallback shutter,

Camera.PictureCallback raw,

Camera.PictureCallback postview,

Camera.PictureCallback jpeg) ------ 拍照

在使用摄像头前,先要给它一些权限(将下列权限代码写入AndroidManifest.xml中)。

<!-- 闪光灯权限 -->
<uses-permission android:name="android.permission.FLASHLIGHT" />
<!-- 调用摄像头权限 -->
<uses-permission android:name="android.permission.CAMERA"/>
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.autofocus"/>
<!-- 读取SD卡权限 -->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>


还有就是设置一下拍照时一直为竖屏。

android:screenOrientation="portrait"


现在就开始对拍照的界面进行布局,一个SurfaceView,三个ImageButton,SurfaceView用于显示预览图像,ImageButton分别用于设置,拍照和相册(暂时还没有做什么前后摄像头切换等等功能)。

下面就是xml的内容:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.photomanager.MainActivity" >

<SurfaceView
android:id="@+id/sfv_photo"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>

<ImageButton
android:id="@+id/ibtn_paizhao"
android:background="#00000000"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="0dp"
android:src="@drawable/takepic" />

<ImageButton
android:id="@+id/ibtn_shezhi"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/sfv_photo"
android:layout_alignTop="@+id/ibtn_paizhao"
android:layout_marginLeft="40dp"
android:background="#00000000"
android:src="@drawable/shezhi" />

<ImageButton
android:id="@+id/ibtn_xiangce"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignRight="@+id/sfv_photo"
android:layout_alignTop="@+id/ibtn_paizhao"
android:layout_marginRight="40dp"
android:background="#00000000"
android:src="@drawable/xiangce" />

</RelativeLayout>


布局搞好了,对于该布局就要有对应的activity来KO它啦。

我们知道,程序的主入口都是MainActivity(在AndroidManifest.xml中配置的),对于拍照,那么显然不能把拍的照片放在手机存储空间中,当然要放在SD卡中(手机存储空间辣么小,再放NNNNN张图片,那不爆了啊?),那么,对于程序运行时,就要开始判断是否SD卡已插入,如果没有,那么直接关闭程序。

//判断SD卡是否插入
if(Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED) != true) {
new AlertDialog.Builder(this).setTitle("Error").setMessage("SD卡未插入,请检查SD卡插入情况!").setPositiveButton("确定",
new DialogInterface.OnClickListener() {

@Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
}).show();
return;
}


在MainActivity中加载好那些控件之后,就要对SurfaceView这个控件进行单独的处理了(这里使用了一个新的类CameraView来处理)。

surfaceview = (SurfaceView) findViewById(R.id.sfv_photo);
surfaceholder = surfaceview.getHolder();
cameraview = new CameraView(this);
surfaceholder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);//指定Push Buffer
surfaceholder.addCallback(cameraview);


对于CameraView类,对它实现SurfaceHolder.Callback接口。

对于该接口,要实现如下3个方法,surfaceCreated、surfaceChanged和surfaceDestroyed。

在surfaceCreated中实现如下:

@Override
public void surfaceCreated(SurfaceHolder holder) {
Log.d("surface", "surfaceCreated");
camera = Camera.open(); //打开相机服务
try {
camera.setPreviewDisplay(holder);  //设置预览
initCamera(); //相机初始化

} catch (IOException e) {
e.printStackTrace();
}
}


在surfaceChanged无实现内容。

在surfaceDestroyed中实现如下:

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
if(camera != null) {
Log.d("surface", "surfaceDestroyed");
camera.stopPreview();  //停止预览
camera.release(); //释放相机服务
camera = null; //置为空
}
}


然后我们需要初始化相机initCamera();

public void initCamera() {
Log.d("surface", "initCamera");
parameters = camera.getParameters(); //得到相机参数

List<Size> previewSizes = parameters.getSupportedPreviewSizes();      //获取相机预览支持尺寸
Size size = MyCamPara.getInstance().getPreviewSize(previewSizes, MainActivity.screenHeight );
parameters.setPreviewSize(size.width, size.height); //设置预览尺寸

List<Size> pictureSizes = parameters.getSupportedPictureSizes();      //获取相机拍照支持尺寸
Size size2 = MyCamPara.getInstance().getPictureSize(pictureSizes, 800);
parameters.setPictureSize(size2.width, size2.height); //设置照片尺寸

parameters.setPictureFormat(PixelFormat.JPEG);   //设置照片格式
if(isSGD) {
parameters.setFlashMode(Parameters.FLASH_MODE_TORCH);     //开启闪光灯
}
else {
parameters.setFlashMode(Parameters.FLASH_MODE_OFF);  //关闭
}

parameters.set("orientation", "portrait");
camera.setDisplayOrientation(90);  //预览旋转90度(不然你预览时是横着的)
parameters.setRotation(90);
camera.setParameters(parameters);//设置参数
camera.startPreview();//开始预览
camera.autoFocus(null);
}


相机这些做完之后,就可以拍照了,那么就调用takePicture(null, null, pictureCallback);就可以了,不过之前得先stopPreview();

对于pictureCallback做如下处理:

Camera.PictureCallback pictureCallback = new Camera.PictureCallback() {

@Override
public void onPictureTaken(byte[] data, Camera camera) {
//data 为照片的字节码数据,通过转化为Bitmap来保存到手机中
}
};


具体怎么实现对拍取的照片的处理,按需求进行编写代码(我这个就比较啰嗦,就不写了,反正就是对data数据处理,具体是拍完照就保存还是拍完照按某某某要求保存看自己了)。

好了,先就这样把~感冒了有(好)点(难)累(受)!~!~!~ 想哭 QwQ~


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: