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; } }