Android自定义照相机实现(拍照、保存到SD卡,利用Bundle在Aciti

Android自定义照相机实现

近期小巫在学校有一个创新项目,也不是最近,是一个拖了很久的项目,之前一直没有去搞,最近因为要中期检查,搞得我跟小组成员一阵忙活,其实开发一款照相机软件并不太难,下面就是通过自定义的方式来实现手机照相的功能。

创建一个项目:FingerTakePicture

首先来搞一下界面:

<FrameLayout xmlns:android=""xmlns:tools=""android:id="@+id/FrameLayout1"android:layout_width="match_parent"android:layout_height="match_parent" ><!– 显示预览图形 –><SurfaceViewandroid:id="@+id/surfaceView"android:layout_width="match_parent"android:layout_height="match_parent"/><!– 相对布局,放置两个按钮 –> <RelativeLayoutandroid:id="@+id/buttonLayout"android:layout_width="wrap_content"android:layout_height="wrap_content"android:visibility="gone"><!– 拍照按钮 –><Buttonandroid:id="@+id/takepicture"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentRight="true"android:layout_alignParentBottom="true"android:background="@drawable/btn_tabkepicture_selector"android:onClick="btnOnclick"/><ImageViewandroid:id="@+id/scalePic"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentLeft="true"android:layout_alignParentBottom="true"android:layout_marginLeft="5dp"android:background="@drawable/img_showpic_selector"android:onClick="imageClick"/></RelativeLayout></FrameLayout>界面效果(无法把预览给截屏下来滴):

权限设置少不了:

<manifest xmlns:android=""package="com.wwj.finger"android:versionCode="1"android:versionName="1.0" ><uses-sdkandroid:minSdkVersion="4"android:targetSdkVersion="15" /><uses-permission android:name="android.permission.CAMERA" /><!– 在SDCard中创建与删除文件权限 –><uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /><!– 往SDCard写入数据权限 –><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><applicationandroid:icon="@drawable/ic_launcher"android:label="@string/app_name"android:theme="@style/AppTheme" ><activityandroid:name=".MainActivity"android:label="@string/title_activity_main"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity><activityandroid:name=".ShowPicActivity"android:label="@string/app_name"android:theme="@style/AppTheme"android:configChanges="orientation|keyboardHidden"></activity></application></manifest>主Activity:

package com.wwj.finger;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.text.SimpleDateFormat;import java.util.Date;import android.app.Activity;import android.content.Intent;import android.graphics.PixelFormat;import android.hardware.Camera;import android.hardware.Camera.PictureCallback;import android.os.Bundle;import android.os.Environment;import android.view.KeyEvent;import android.view.MotionEvent;import android.view.Surface;import android.view.SurfaceHolder;import android.view.SurfaceHolder.Callback;import android.view.SurfaceView;import android.view.View;import android.view.ViewGroup;import android.widget.Toast;/** * Android手指拍照 * * @author wwj * @date 2013/4/29 */public class MainActivity extends Activity {private View layout;private Camera camera;private Camera.Parameters parameters = null;Bundle bundle = null; // 声明一个Bundle对象,用来存储数据@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);// 显示界面setContentView(R.layout.activity_main);layout = this.findViewById(R.id.buttonLayout);SurfaceView surfaceView = (SurfaceView) this.findViewById(R.id.surfaceView);surfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);surfaceView.getHolder().setFixedSize(176, 144);//设置Surface分辨率surfaceView.getHolder().setKeepScreenOn(true);// 屏幕常亮surfaceView.getHolder().addCallback(new SurfaceCallback());//为SurfaceView的句柄添加一个回调函数}/** * 按钮被点击触发的事件 * * @param v */public void btnOnclick(View v) {if (camera != null) {switch (v.getId()) {case R.id.takepicture:// 拍照camera.takePicture(null, null, new MyPictureCallback());break;}}}/** * 图片被点击触发的时间 * * @param v */public void imageClick(View v) {if (v.getId() == R.id.scalePic) {if (bundle == null) {Toast.makeText(getApplicationContext(), R.string.takephoto,Toast.LENGTH_SHORT).show();} else {Intent intent = new Intent(this, ShowPicActivity.class);intent.putExtras(bundle);startActivity(intent);}}}private final class MyPictureCallback implements PictureCallback {@Overridepublic void onPictureTaken(byte[] data, Camera camera) {try {bundle = new Bundle();bundle.putByteArray("bytes", data);//将图片字节数据保存在bundle当中,实现数据交换saveToSDCard(data); // 保存图片到sd卡中Toast.makeText(getApplicationContext(), R.string.success,Toast.LENGTH_SHORT).show();camera.startPreview(); // 拍完照后,,重新开始预览} catch (Exception e) {e.printStackTrace();}}}/** * 将拍下来的照片存放在SD卡中 * @param data * @throws IOException */public static void saveToSDCard(byte[] data) throws IOException {Date date = new Date();SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss"); // 格式化时间String filename = format.format(date) + ".jpg";File fileFolder = new File(Environment.getExternalStorageDirectory()+ "/finger/");if (!fileFolder.exists()) { // 如果目录不存在,则创建一个名为"finger"的目录fileFolder.mkdir();}File jpgFile = new File(fileFolder, filename);FileOutputStream outputStream = new FileOutputStream(jpgFile); // 文件输出流outputStream.write(data); // 写入sd卡中outputStream.close(); // 关闭输出流}private final class SurfaceCallback implements Callback {// 拍照状态变化时调用该方法@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {parameters = camera.getParameters(); // 获取各项参数parameters.setPictureFormat(PixelFormat.JPEG); // 设置图片格式parameters.setPreviewSize(width, height); // 设置预览大小parameters.setPreviewFrameRate(5);//设置每秒显示4帧parameters.setPictureSize(width, height); // 设置保存的图片尺寸parameters.setJpegQuality(80); // 设置照片质量}// 开始拍照时调用该方法@Overridepublic void surfaceCreated(SurfaceHolder holder) {try {camera = Camera.open(); // 打开摄像头camera.setPreviewDisplay(holder); // 设置用于显示拍照影像的SurfaceHolder对象camera.setDisplayOrientation(getPreviewDegree(MainActivity.this));camera.startPreview(); // 开始预览} catch (Exception e) {e.printStackTrace();}}// 停止拍照时调用该方法@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {if (camera != null) {camera.release(); // 释放照相机camera = null;}}}/** * 点击手机屏幕是,显示两个按钮 */@Overridepublic boolean onTouchEvent(MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_DOWN:layout.setVisibility(ViewGroup.VISIBLE); // 设置视图可见break;}return true;}@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {switch (keyCode) {case KeyEvent.KEYCODE_CAMERA: // 按下拍照按钮if (camera != null && event.getRepeatCount() == 0) {// 拍照//注:调用takePicture()方法进行拍照是传入了一个PictureCallback对象——当程序获取了拍照所得的图片数据之后//,PictureCallback对象将会被回调,该对象可以负责对相片进行保存或传入网络camera.takePicture(null, null, new MyPictureCallback());}}return super.onKeyDown(keyCode, event);}// 提供一个静态方法,用于根据手机方向获得相机预览画面旋转的角度public static int getPreviewDegree(Activity activity) {// 获得手机的方向int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();int degree = 0;// 根据手机的方向计算相机预览画面应该选择的角度switch (rotation) {case Surface.ROTATION_0:degree = 90;break;case Surface.ROTATION_90:degree = 0;break;case Surface.ROTATION_180:degree = 270;break;case Surface.ROTATION_270:degree = 180;break;}return degree;}}

用来显示图片的Activity:

即使是不成熟的尝试,也胜于胎死腹中的策略。

Android自定义照相机实现(拍照、保存到SD卡,利用Bundle在Aciti

相关文章:

你感兴趣的文章:

标签云: