写点什么

Android 自定义照相机实现(拍照、保存到 SD 卡,利用 Bundle 在 Acitivity 交换数据

用户头像
Android架构
关注
发布于: 17 小时前

android:id="@+id/FrameLayout1"


android:layout_width="match_parent"


android:layout_height="match_parent" >


<SurfaceView


android:id="@+id/surfaceView"


android:layout_width="match_parent"


android:layout_height="match_parent"


/>


<RelativeLayout


android:id="@+id/buttonLayout"


android:layout_width="wrap_content"


android:layout_height="wrap_content"


android:visibility="gone"



<Button


android: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"


/>


<ImageView


android: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="http://schemas.android.com/apk/res/android"


package="com.wwj.finger"


android:versionCode="1"


android:versionName="1.0" >


<uses-sdk


android:minSdkVersion="4"


android:targetSdkVersion="15" />


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


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


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


<application


android:icon="@drawable/ic_launcher"


android:label="@string/app_name"


android:theme="@style/AppTheme" >


<activity


android: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>


<activity


android: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 对象,用来存储数据


@Override


public 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 int


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


ent = new Intent(this, ShowPicActivity.class);


intent.putExtras(bundle);


startActivity(intent);


}


}


}


private final class MyPictureCallback implements PictureCallback {


@Override


public 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 {


// 拍照状态变化时调用该方法


@Override


public 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); // 设置照片质量


}


// 开始拍照时调用该方法


@Override


public void surfaceCreated(SurfaceHolder holder) {


try {


camera = Camera.open(); // 打开摄像头


camera.setPreviewDisplay(holder); // 设置用于显示拍照影像的 SurfaceHolder 对象


camera.setDisplayOrientation(getPreviewDegree(MainActivity.this));


camera.startPreview(); // 开始预览


} catch (Exception e) {


e.printStackTrace();


}


}


// 停止拍照时调用该方法


@Override


public void surfaceDestroyed(SurfaceHolder holder) {


if (camera != null) {


camera.release(); // 释放照相机


camera = null;


}


}


}


/**


  • 点击手机屏幕是,显示两个按钮


*/


@Override


public boolean onTouchEvent(MotionEvent event) {


switch (event.getAction()) {


case MotionEvent.ACTION_DOWN:


layout.setVisibility(ViewGroup.VISIBLE); // 设置视图可见


break;


}


return true;


}


@Override


public 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());

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
Android自定义照相机实现(拍照、保存到SD卡,利用Bundle在Acitivity交换数据