package com.jqyd.camera.library;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import com.example.camera.R;
import com.jqyd.camera.library.AccessoryDTO;
import com.jqyd.utils.PhotoUtil;
import com.jqyd.utils.UIUtil;
import com.jqyd.utils.VerticalSeekBar;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.hardware.Camera.AutoFocusCallback;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.ShutterCallback;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.KeyEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
public class CustomCameraActivity extends Activity implements SurfaceHolder.Callback{
/**
* 负责定义页面数据变量
*/
private Activity context;
private static final String tag="camera";
private boolean isPreview = false;
private SurfaceHolder mHolder;
private Camera mCamera;
private Bitmap cameraBitmap;
private ProgressDialog dialog;
/**
* 负责定义页面显示控件变量
*/
private Button btn_Save;
private Button btn_Concel;
private Button btn_Posing;
private SurfaceView surfaceView;
private VerticalSeekBar seekBar_Zoom;
private RelativeLayout lay_surfaceView;
private RelativeLayout lay_PictureView;
private ImageView PictureView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 初始化界参数
initPara();
// 初始化界面控件
initUI();
// 添加事件监听
regListener();
}
/**
* 初始化界参数
*/
private void initPara() {
context=this;
dialog=new ProgressDialog(context);
}
/**
* 系统返回键控制
*/
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN&& event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
if(!isPreview){
if(cameraBitmap!=null){
cameraBitmap.recycle();
cameraBitmap=null;
}
//显示拍照视图
PosingShow(true);
mCamera.startPreview();
isPreview=true;
}else{
UIUtil.finishFunction(context);
}
return true;
} else {
return super.dispatchKeyEvent(event);
}
}
/**
* 初始化界面控件
*/
private void initUI() {
//设置全屏无标题
requestWindowFeature(Window.FEATURE_NO_TITLE);
int flag = WindowManager.LayoutParams.FLAG_FULLSCREEN;
Window myWindow = this.getWindow();
myWindow.setFlags(flag, flag);
setContentView(R.layout.camera);
// 获取控件
btn_Save = (Button) findViewById(R.id.btn_Save);
btn_Concel = (Button) findViewById(R.id.btn_Cancel);
btn_Posing = (Button) findViewById(R.id.btn_Posing);
surfaceView = (SurfaceView) findViewById(R.id.surfaceView);
seekBar_Zoom =(VerticalSeekBar) findViewById(R.id.seekBar_Zoom);
lay_surfaceView = (RelativeLayout) findViewById(R.id.lay_surfaceView);
lay_PictureView = (RelativeLayout) findViewById(R.id.lay_PictureView);
PictureView = (ImageView) findViewById(R.id.PictureView);
//初始化mHolder
mHolder = surfaceView.getHolder();
//translucent半透明 transparent透明
mHolder.setFormat(PixelFormat.TRANSLUCENT);
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
/**
* 控制拍照状态和显示图片状态的按钮显示和隐藏
* @param b
*/
private void PosingShow(boolean b){
if(b){
lay_surfaceView.setVisibility(View.VISIBLE);
lay_PictureView.setVisibility(View.GONE);
PictureView.setImageBitmap(null);
btn_Posing.setVisibility(View.VISIBLE);
btn_Save.setVisibility(View.GONE);
if(isSupportZoom()){
seekBar_Zoom.setVisibility(View.VISIBLE);
}else{
seekBar_Zoom.setVisibility(View.GONE);
}
}else{
lay_surfaceView.setVisibility(View.GONE);
lay_PictureView.setVisibility(View.VISIBLE);
PictureView.setImageBitmap(cameraBitmap);
btn_Posing.setVisibility(View.GONE);
btn_Save.setVisibility(View.VISIBLE);
}
}
/**********下面三个是SurfaceHolder.Callback创建的回调函数**********************/
@Override
// 当SurfaceView/预览界面的格式和大小发生改变时,该方法被调用
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
initCamera();
}
@Override
// SurfaceView启动时/初次实例化,预览界面被创建时,该方法被调用。
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
mCamera = Camera.open();
//默认显示拍照按钮
PosingShow(true);
try {
mCamera.setPreviewDisplay(mHolder);
Log.i(tag, "SurfaceHolder.Callback: surfaceCreated!");
} catch (IOException e) {
// TODO Auto-generated catch block
if (null != mCamera) {
mCamera.release();
mCamera = null;
}
e.printStackTrace();
}
}
@Override
//销毁时被调用
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
if(mCamera!=null){
mCamera.setPreviewCallback(null);
mCamera.stopPreview();
isPreview = false;
mCamera.release();
mCamera = null;
}
}
/**
* 初始化相机参数
*/
private void initCamera(){
if(mCamera==null){
mCamera = Camera.open();
}
Camera.Parameters parameters = mCamera.getParameters();
// 选择合适的预览尺寸
List<Camera.Size> sizeList = parameters.getSupportedPreviewSizes();
Camera.Size cameraSize = (Camera.Size) sizeList.get(1);
//设置预览图的大小
parameters.setPreviewSize(cameraSize.width, cameraSize.height);
//设置预览图的帧数
parameters.setPreviewFrameRate(5);
//设置图片输出格式
parameters.setPictureFormat(PixelFormat.JPEG);
parameters.set("jpeg-quality", 100);
//控制影响生成的图片尺寸
parameters.setPictureSize(1280, 960);
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
//系统默认摄像头为横向
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
//如果是屏幕纵向,摄像头旋转90度;
mCamera.setDisplayOrientation(90);
}
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
//如果是屏幕横向,摄像头旋转0度;
parameters.set("orientation", "landscape");
parameters.set("rotation", 0);
}
//自动对焦
//mCamera.autoFocus(myAutoFocusCallback);
mCamera.setParameters(parameters);
try {
mCamera.setPreviewDisplay(mHolder);
} catch (IOException e) {
System.out.println(e.getMessage());
mCamera.release();
mCamera = null;
}
//开始预览
mCamera.startPreview();
isPreview = true;
}
/**
* 自动聚焦变量回调
*/
private AutoFocusCallback myAutoFocusCallback = new AutoFocusCallback() {
public void onAutoFocus(boolean success, Camera camera) {
if (success) {
Log.i(tag, "autofocus: success...");
//mCamera.setOneShotPreviewCallback(previewCallback);
} else {
Log.i("autofocus:", "fail");
}
}
};
/* 为了实现拍照的快门声音及拍照保存照片需要下面三个回调变量 */
ShutterCallback myShutterCallback = new ShutterCallback()
// 快门按下的回调,在这里我们可以设置类似播放“咔嚓”声之类的操作。默认的就是咔嚓。
{
public void onShutter() {
// TODO Auto-generated method stub
Log.i(tag, "myShutterCallback:onShutter...");
}
};
PictureCallback myRawCallback = new PictureCallback()
// 拍摄的未压缩原数据的回调,可以为null
{
public void onPictureTaken(byte[] data, Camera camera) {
// TODO Auto-generated method stub
Log.i(tag, "myRawCallback:onPictureTaken...");
}
};
/**
* 拍照回调函数,保存并显示 通过PictureCallback实现
*/
private PictureCallback myJpegCallback = new PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
if(data!=null){
if(cameraBitmap!=null){
cameraBitmap.recycle();
}
//图像默认为横向
int ori=getResources().getConfiguration().orientation;
if (ori == Configuration.ORIENTATION_LANDSCAPE) {
//当屏幕为横向时无需旋转
cameraBitmap=BitmapFactory.decodeByteArray(data, 0, data.length);
}
if (ori == Configuration.ORIENTATION_PORTRAIT) {
//得到照片图像,默认偏移90度,此时需将图片旋转90度,得到正常图片
Bitmap bm=BitmapFactory.decodeByteArray(data, 0, data.length);
//旋转得到正常图片
Matrix matrix = new Matrix();
matrix.postRotate((float)90.0);
cameraBitmap = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), matrix, false);
bm.recycle();
}
mCamera.stopPreview();
isPreview = false;
}
//显示保存按钮
PosingShow(false);
if(dialog.isShowing()){
dialog.dismiss();
}
}
};
/**
* 保存图片数据
*/
public String SavePciture() {
String result="";
PhotoUtil.PhotoName=PhotoUtil.createPhotoName();
String filepath=PhotoUtil.SDCARD_ROOT_PATH + PhotoUtil.SAVE_PATH_IN_SDCARD;
File f = new File(filepath);
if (!f.exists()) {
f.mkdirs();
}
File myCaptureFile = new File(PhotoUtil.getPhotoPath());
try {
FileOutputStream fout = new FileOutputStream(myCaptureFile);
BufferedOutputStream bos = new BufferedOutputStream(fout);
// 如果需要改变大小(默认的是宽960×高1280),如改成宽600×高800
// Bitmap newBM = bm.createScaledBitmap(bm, 600, 800, false);
cameraBitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);
bos.flush();
bos.close();
cameraBitmap.recycle();
cameraBitmap=null;
result="success";
Log.i(tag, "saveJpeg:存储完毕!");
} catch (Exception e) {
result="error";
Log.i(tag, "saveJpeg:存储失败!");
e.getStackTrace();
}
return result;
}
Handler handler = new Handler() {
public void handleMessage(Message msg) {
String res=(String) msg.obj;
if(msg.what==1 && res.equals("success")){
Intent intent = new Intent();
AccessoryDTO photo=new AccessoryDTO();
photo.setPath(PhotoUtil.getPhotoPath());
photo.setName(PhotoUtil.PhotoName);
photo.setType(AccessoryDTO.AccessoryType.image.getCode());
intent.putExtra("m", photo);
setResult(RESULT_OK, intent);
}else{
UIUtil.alertMsg(context, "存储照片失败");
}
if(dialog.isShowing()){
dialog.dismiss();
}
PhotoUtil.Clear();
UIUtil.finishFunction(context);
}
};
/**
* 添加事件监听
*/
private void regListener() {
//调焦距滚动条改变触发焦距改变
seekBar_Zoom.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
// TODO Auto-generated method stub
if (isSupportZoom()) {
try {
Camera.Parameters params = mCamera.getParameters();
int zmax=params.getMaxZoom();
int pmax=seekBar.getMax();
if(zmax==0){
return;
}else{
int zoomValue=0;
if(pmax==progress){
zoomValue=zmax;
}else if(0==progress){
zoomValue=0;
}else {
zoomValue = zmax*progress/pmax;
}
params.setZoom(zoomValue);
mCamera.setParameters(params);
}
} catch (Exception e) {
Log.e(tag, "--exception zoom");
e.printStackTrace();
}
} else {
Log.e(tag, "--the phone not support zoom");
}
}
});
//拍照按钮处理程序
btn_Posing.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if(!dialog.isShowing()){
dialog.setMessage("正在显示照片,请稍候...");
dialog.show();
}
if (isPreview && mCamera != null) {
mCamera.takePicture(myShutterCallback, null, myJpegCallback);
}
}
});
//完成按钮,保存数据,并返回
btn_Save.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if(!dialog.isShowing()){
dialog.setMessage("正在保存照片,请稍候...");
dialog.show();
}
Thread task=new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
//保存图片数据
String res=SavePciture();
handler.obtainMessage(1,res).sendToTarget();
}
});
task.start();
}
});
//取消保存照片按钮处理程序
btn_Concel.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if(!isPreview){
if(cameraBitmap!=null){
cameraBitmap.recycle();
cameraBitmap=null;
}
//显示拍照视图
PosingShow(true);
mCamera.startPreview();
isPreview=true;
}else{
UIUtil.finishFunction(context);
}
}
});
}
/**
* 判断是否支持变焦
* @return
*/
public boolean isSupportZoom() {
boolean isSuppport = true;
if(mCamera!=null){
if (mCamera.getParameters().isSmoothZoomSupported()) {
isSuppport = false;
}
}
return isSuppport;
}
}