在网上找了很多拍照功能的实现代码,但都不是很理想,结合别人的代码实现了一个自己的拍照功能的代码,该代码已经使用到了项目中,现分享出来,代码如下:
{CSDN:CODE:/**
* 拍照功能
*
* @author shiping.luo
*
*/
public class TakePhotoActivity extends Activity implements
SurfaceHolder.Callback, OnClickListener {
private String imgPath = Environment.getExternalStorageDirectory()
.getPath() + Constants.IMAGE_PATH;
private ImageView iv_file, iv_camera, iv_exit;
private SurfaceView surfaceView;
private SurfaceHolder surfaceHolder;
private Camera mCamera; // 照相机
ProgressDialog dialog = null;
Handler handler = new Handler(){
public void handleMessage(android.os.Message msg) {
if(msg.what==1){
if(dialog != null){
dialog.dismiss();
}
}
};
};
private String attachmentID;//主键
private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
@Override
protected void onCreate(Bundle arg0) {
super.onCreate(arg0);
// 隐藏状态栏和标题栏
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); // 竖屏
setContentView(R.layout.check_take_photo);
setupViews();
//imgPath =File.separator+sdf.format(new Date());
}
protected void setupViews() {
attachmentID=getIntent().getStringExtra("attachmentID");
iv_file = (ImageView) findViewById(R.id.iv_file);
iv_camera = (ImageView) findViewById(R.id.iv_camera);
iv_exit = (ImageView) findViewById(R.id.iv_exit);
iv_file.setOnClickListener(this);
iv_camera.setOnClickListener(this);
iv_exit.setOnClickListener(this);
surfaceView = (SurfaceView) findViewById(R.id.surface_camera);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
checkSoftStage(); // 首先检测SD卡是否存在
}
/**
* 检测手机是否存在SD卡,网络连接是否打开
*/
private void checkSoftStage() {
if (Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) { // 判断是否存在SD卡
File file = new File(imgPath);
if (!file.exists()) {
file.mkdirs();
}
} else {
new AlertDialog.Builder(this)
.setMessage("检测到手机没有存储卡!请插入手机存储卡再开启本应用。")
.setPositiveButton("确定",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
finish();
}
}).show();
}
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.iv_camera:
mCamera.autoFocus(new AutoFoucus()); // 自动对焦
break;
case R.id.iv_exit:
finish();
break;
case R.id.iv_file:
break;
}
}
/**
* 自动对焦后拍照
*
* @author shiping.luo
* @Date 2011-12-5
*/
private final class AutoFoucus implements AutoFocusCallback {
@Override
public void onAutoFocus(boolean success, Camera camera) {
if (success && mCamera != null) {
mCamera.takePicture(mShutterCallback, null, mPictureCallback);
}
}
}
/**
* 重点对象、 此处实例化了一个本界面的PictureCallback 当用户拍完一张照片的时候触发,这时候对图片处理并保存操作。
*
*/
private final PictureCallback mPictureCallback = new PictureCallback() {
@Override
public void onPictureTaken(final byte[] data, Camera camera) {
dialog = ProgressDialog.show(TakePhotoActivity.this, "操作提示", "正在生成文件...");
new Thread(){
public void run() {
try {
String fileName = UUID.randomUUID() + ".jpg";
File file = new File(imgPath, fileName);
// Bitmap bm = BitmapFactory.decodeByteArray(data, 0,
// data.length);
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
// 竖屏时,旋转图片再保存
Bitmap oldBitmap = BitmapFactory.decodeByteArray(data, 0,
data.length,options);
options.inSampleSize = calculateInSampleSize(options, 480, 800);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
oldBitmap =BitmapFactory.decodeByteArray(data, 0,
data.length,options);
Matrix matrix = new Matrix();
matrix.setRotate(90);
Bitmap newBitmap = Bitmap.createBitmap(oldBitmap, 0, 0,
oldBitmap.getWidth(), oldBitmap.getHeight(), matrix,
true);
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream(file));
newBitmap.compress(Bitmap.CompressFormat.JPEG, 60, bos);
bos.flush();
bos.close();
oldBitmap.recycle();
newBitmap.recycle();
handler.sendEmptyMessage(1);
} catch (Exception e) {
e.printStackTrace();
handler.sendEmptyMessage(1);
}
};
}.start();
}
};
// 计算图片的缩放值
public static int calculateInSampleSize(BitmapFactory.Options options,
int reqWidth, int reqHeight) {
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int heightRatio = Math.round((float) height
/ (float) reqHeight);
final int widthRatio = Math.round((float) width / (float) reqWidth);
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
}
return inSampleSize;
}
// 取能适用的最大的SIZE
private Size getBestSupportedSize(List<Size> sizes) {
// 取能适用的最大的SIZE
Size largestSize = sizes.get(0);
int largestArea = sizes.get(0).height * sizes.get(0).width;
for (Size s : sizes) {
int area = s.width * s.height;
if (area > largestArea) {
largestArea = area;
largestSize = s;
}
}
return largestSize;
}
/**
* 在相机快门关闭时候的回调接口,通过这个接口来通知用户快门关闭的事件,
* 普通相机在快门关闭的时候都会发出响声,根据需要可以在该回调接口中定义各种动作, 例如:使设备震动
*/
private final ShutterCallback mShutterCallback = new ShutterCallback() {
public void onShutter() {
Log.d("ShutterCallback", "...onShutter...");
}
};
@Override
/**
* 初始化相机参数,比如相机的参数: 像素, 大小,格式
*/
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
Camera.Parameters param = mCamera.getParameters();
/**
* 设置拍照图片格式
*/
param.setPictureFormat(PixelFormat.JPEG);
/**
* 设置自动对焦
*/
param.setFocusMode("auto");
/**
* 设置预览尺寸
*/
Size largestSize = getBestSupportedSize(param
.getSupportedPreviewSizes());
param.setPreviewSize(largestSize.width, largestSize.height);
// 设置预览图片尺寸
largestSize = getBestSupportedSize(param.getSupportedPictureSizes());
// 设置捕捉图片尺寸
param.setPictureSize(largestSize.width, largestSize.height);
mCamera.setParameters(param);
/**
* 开始预览
*/
mCamera.startPreview();
mCamera.autoFocus(null); // 自动对焦
}
@Override
/**
* 打开相机,设置预览
*/
public void surfaceCreated(SurfaceHolder holder) {
try {
mCamera = Camera.open(); // 打开摄像头
mCamera.setDisplayOrientation(90);
mCamera.setPreviewDisplay(holder);
} catch (IOException e) {
mCamera.release();
mCamera = null;
Toast.makeText(TakePhotoActivity.this, "无法开启照相功能!", Toast.LENGTH_LONG).show();
TakePhotoActivity.this.finish();
}
}
@Override
/**
* 预览界面被关闭时,或者停止相机拍摄;释放相机资源
*/
public void surfaceDestroyed(SurfaceHolder holder) {
mCamera.stopPreview();
if (mCamera != null)
mCamera.release();
mCamera = null;
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_CAMERA) { // 按下相机实体按键,启动本程序照相功能
mCamera.autoFocus(new AutoFoucus()); // 自动对焦
return true;
} else {
return false;
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
// 按下时自动对焦
mCamera.autoFocus(null);
}
return super.onTouchEvent(event);
}
}}
* 拍照功能
*
* @author shiping.luo
*
*/
public class TakePhotoActivity extends Activity implements
SurfaceHolder.Callback, OnClickListener {
private String imgPath = Environment.getExternalStorageDirectory()
.getPath() + Constants.IMAGE_PATH;
private ImageView iv_file, iv_camera, iv_exit;
private SurfaceView surfaceView;
private SurfaceHolder surfaceHolder;
private Camera mCamera; // 照相机
ProgressDialog dialog = null;
Handler handler = new Handler(){
public void handleMessage(android.os.Message msg) {
if(msg.what==1){
if(dialog != null){
dialog.dismiss();
}
}
};
};
private String attachmentID;//主键
private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
@Override
protected void onCreate(Bundle arg0) {
super.onCreate(arg0);
// 隐藏状态栏和标题栏
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); // 竖屏
setContentView(R.layout.check_take_photo);
setupViews();
//imgPath =File.separator+sdf.format(new Date());
}
protected void setupViews() {
attachmentID=getIntent().getStringExtra("attachmentID");
iv_file = (ImageView) findViewById(R.id.iv_file);
iv_camera = (ImageView) findViewById(R.id.iv_camera);
iv_exit = (ImageView) findViewById(R.id.iv_exit);
iv_file.setOnClickListener(this);
iv_camera.setOnClickListener(this);
iv_exit.setOnClickListener(this);
surfaceView = (SurfaceView) findViewById(R.id.surface_camera);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
checkSoftStage(); // 首先检测SD卡是否存在
}
/**
* 检测手机是否存在SD卡,网络连接是否打开
*/
private void checkSoftStage() {
if (Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) { // 判断是否存在SD卡
File file = new File(imgPath);
if (!file.exists()) {
file.mkdirs();
}
} else {
new AlertDialog.Builder(this)
.setMessage("检测到手机没有存储卡!请插入手机存储卡再开启本应用。")
.setPositiveButton("确定",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
finish();
}
}).show();
}
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.iv_camera:
mCamera.autoFocus(new AutoFoucus()); // 自动对焦
break;
case R.id.iv_exit:
finish();
break;
case R.id.iv_file:
break;
}
}
/**
* 自动对焦后拍照
*
* @author shiping.luo
* @Date 2011-12-5
*/
private final class AutoFoucus implements AutoFocusCallback {
@Override
public void onAutoFocus(boolean success, Camera camera) {
if (success && mCamera != null) {
mCamera.takePicture(mShutterCallback, null, mPictureCallback);
}
}
}
/**
* 重点对象、 此处实例化了一个本界面的PictureCallback 当用户拍完一张照片的时候触发,这时候对图片处理并保存操作。
*
*/
private final PictureCallback mPictureCallback = new PictureCallback() {
@Override
public void onPictureTaken(final byte[] data, Camera camera) {
dialog = ProgressDialog.show(TakePhotoActivity.this, "操作提示", "正在生成文件...");
new Thread(){
public void run() {
try {
String fileName = UUID.randomUUID() + ".jpg";
File file = new File(imgPath, fileName);
// Bitmap bm = BitmapFactory.decodeByteArray(data, 0,
// data.length);
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
// 竖屏时,旋转图片再保存
Bitmap oldBitmap = BitmapFactory.decodeByteArray(data, 0,
data.length,options);
options.inSampleSize = calculateInSampleSize(options, 480, 800);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
oldBitmap =BitmapFactory.decodeByteArray(data, 0,
data.length,options);
Matrix matrix = new Matrix();
matrix.setRotate(90);
Bitmap newBitmap = Bitmap.createBitmap(oldBitmap, 0, 0,
oldBitmap.getWidth(), oldBitmap.getHeight(), matrix,
true);
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream(file));
newBitmap.compress(Bitmap.CompressFormat.JPEG, 60, bos);
bos.flush();
bos.close();
oldBitmap.recycle();
newBitmap.recycle();
handler.sendEmptyMessage(1);
} catch (Exception e) {
e.printStackTrace();
handler.sendEmptyMessage(1);
}
};
}.start();
}
};
// 计算图片的缩放值
public static int calculateInSampleSize(BitmapFactory.Options options,
int reqWidth, int reqHeight) {
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int heightRatio = Math.round((float) height
/ (float) reqHeight);
final int widthRatio = Math.round((float) width / (float) reqWidth);
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
}
return inSampleSize;
}
// 取能适用的最大的SIZE
private Size getBestSupportedSize(List<Size> sizes) {
// 取能适用的最大的SIZE
Size largestSize = sizes.get(0);
int largestArea = sizes.get(0).height * sizes.get(0).width;
for (Size s : sizes) {
int area = s.width * s.height;
if (area > largestArea) {
largestArea = area;
largestSize = s;
}
}
return largestSize;
}
/**
* 在相机快门关闭时候的回调接口,通过这个接口来通知用户快门关闭的事件,
* 普通相机在快门关闭的时候都会发出响声,根据需要可以在该回调接口中定义各种动作, 例如:使设备震动
*/
private final ShutterCallback mShutterCallback = new ShutterCallback() {
public void onShutter() {
Log.d("ShutterCallback", "...onShutter...");
}
};
@Override
/**
* 初始化相机参数,比如相机的参数: 像素, 大小,格式
*/
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
Camera.Parameters param = mCamera.getParameters();
/**
* 设置拍照图片格式
*/
param.setPictureFormat(PixelFormat.JPEG);
/**
* 设置自动对焦
*/
param.setFocusMode("auto");
/**
* 设置预览尺寸
*/
Size largestSize = getBestSupportedSize(param
.getSupportedPreviewSizes());
param.setPreviewSize(largestSize.width, largestSize.height);
// 设置预览图片尺寸
largestSize = getBestSupportedSize(param.getSupportedPictureSizes());
// 设置捕捉图片尺寸
param.setPictureSize(largestSize.width, largestSize.height);
mCamera.setParameters(param);
/**
* 开始预览
*/
mCamera.startPreview();
mCamera.autoFocus(null); // 自动对焦
}
@Override
/**
* 打开相机,设置预览
*/
public void surfaceCreated(SurfaceHolder holder) {
try {
mCamera = Camera.open(); // 打开摄像头
mCamera.setDisplayOrientation(90);
mCamera.setPreviewDisplay(holder);
} catch (IOException e) {
mCamera.release();
mCamera = null;
Toast.makeText(TakePhotoActivity.this, "无法开启照相功能!", Toast.LENGTH_LONG).show();
TakePhotoActivity.this.finish();
}
}
@Override
/**
* 预览界面被关闭时,或者停止相机拍摄;释放相机资源
*/
public void surfaceDestroyed(SurfaceHolder holder) {
mCamera.stopPreview();
if (mCamera != null)
mCamera.release();
mCamera = null;
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_CAMERA) { // 按下相机实体按键,启动本程序照相功能
mCamera.autoFocus(new AutoFoucus()); // 自动对焦
return true;
} else {
return false;
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
// 按下时自动对焦
mCamera.autoFocus(null);
}
return super.onTouchEvent(event);
}
}}
布局文件:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<SurfaceView
android:id="@+id/surface_camera"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentBottom="true"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"/>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="50dp"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:background="@drawable/check_take_photo_big"
android:paddingTop="5dp"
android:paddingBottom="5dp">
<ImageView
android:id="@+id/iv_file"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_weight="1"
android:src="@drawable/camera_image" />
<ImageView
android:id="@+id/iv_camera"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_weight="1"
android:src="@drawable/camera_cap" />
<ImageView
android:id="@+id/iv_exit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_marginLeft="22dp"
android:layout_weight="1"
android:src="@drawable/camera_cancel" />
</RelativeLayout>
</RelativeLayout>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<SurfaceView
android:id="@+id/surface_camera"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentBottom="true"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"/>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="50dp"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:background="@drawable/check_take_photo_big"
android:paddingTop="5dp"
android:paddingBottom="5dp">
<ImageView
android:id="@+id/iv_file"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_weight="1"
android:src="@drawable/camera_image" />
<ImageView
android:id="@+id/iv_camera"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_weight="1"
android:src="@drawable/camera_cap" />
<ImageView
android:id="@+id/iv_exit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_marginLeft="22dp"
android:layout_weight="1"
android:src="@drawable/camera_cancel" />
</RelativeLayout>
</RelativeLayout>