package com.wistron.WiCamera;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.Size;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
/**
*
* @Copyright (c) 2012 Wistron SWPC All rights reserved.
*
* @created: 2012/06/21
* @filename: CameraView.java
* @author WH1107063(周海江)
* @purpose 照相的SurfaceView,主要用于打开camera和对camera的操作 ,如打开camera,设置参数,拍照
*
*
*
*
*/
public class CameraView extends SurfaceView implements SurfaceHolder.Callback {
// SurfaceHolder实例
SurfaceHolder mHolder;
// camera实例
Camera mCamera;
// 预览的bitmap
public Bitmap mBitmap = null;
// activity对象
public CameraPreview owner;
byte[] callbackBuffer;
public boolean bFlag = false;
private int mScreenWidth = 800;
private int mScreenHeight = 480;
// 预览图
private Bitmap mbmp_previewL = null;
private Bitmap mbmp_previewR = null;
// 实际拍照图
private Bitmap mbmp_picL = null;
private Bitmap mbmp_picR = null;
private int mCameraID;
public CameraPreview context;
public CameraView(Context context, AttributeSet attributeSet) {
super(context, attributeSet);
this.context = (CameraPreview) context;
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
private Camera.PreviewCallback previewCallback = new Camera.PreviewCallback() {
public void onPreviewFrame(byte[] data, Camera camera) {
}
};
public void takePicture() {
// mCamera.takePicture(shutterCallback, null, pictureCallback);
mCamera.autoFocus(autoFocusCallback);
}
// 准备一个保存图片的PictureCallback对象
public Camera.PictureCallback pictureCallback = new Camera.PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
// 用BitmapFactory.decodeByteArray()方法可以把相机传回的裸数据转换成Bitmap对象
// 拍摄左图
if (bFlag) {
// convertToRBImage(mbmp_previewL, mbmp_previewR, mBitmap);\
dataR = data;
context.mAlpha = 250;
bFlag = false;
context.takePictureFinish();
// 拍摄右图
} else {
mbmp_picL = BitmapFactory.decodeByteArray(data, 0, data.length);
Canvas canvas = new Canvas(mbmp_previewL);
Rect rect1 = new Rect(0, 0, mbmp_picL.getWidth(),
mbmp_picL.getHeight());
Rect rect2 = new Rect(0, 0, mbmp_previewL.getWidth(),
mbmp_previewL.getHeight());
canvas.drawBitmap(mbmp_picL, rect1, rect2, null);
canvas = new Canvas(mBitmap);
canvas.drawBitmap(mbmp_previewL, 0, 0, null);
dataL = data;
bFlag = true;
context.mAlpha = 170;
context.updateImageView();
}
mCamera.startPreview();
context.mHandler.sendEmptyMessage(100);
}
};
public Camera.ShutterCallback shutterCallback = new Camera.ShutterCallback() {
public void onShutter() {
}
};
public Camera.AutoFocusCallback autoFocusCallback = new Camera.AutoFocusCallback() {
public void onAutoFocus(boolean success, Camera camera) {
camera.takePicture(shutterCallback, null, pictureCallback);
}
};
/**
* 把bitmap保存成文件
*
* @param bmp
* @param name
*/
public void saveImage(Bitmap bmp, String name) {
File file = new File(name);
try {
file.createNewFile();
BufferedOutputStream os = new BufferedOutputStream(
new FileOutputStream(file));
bmp.compress(Bitmap.CompressFormat.JPEG, 90, os);
os.flush();
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 设置图片的旋转角度
*
* @param activity
* @param cameraId
* @param camera
*/
public static void setCameraDisplayOrientation(Activity activity,
int cameraId, android.hardware.Camera camera) {
android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
android.hardware.Camera.getCameraInfo(cameraId, info);
int rotation = activity.getWindowManager().getDefaultDisplay()
.getRotation();
int degrees = 0;
switch (rotation) {
case Surface.ROTATION_0:
degrees = 0;
break;
case Surface.ROTATION_90:
degrees = 90;
break;
case Surface.ROTATION_180:
degrees = 180;
break;
case Surface.ROTATION_270:
degrees = 270;
break;
}
int result;
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
result = (info.orientation + degrees) % 360;
result = (360 - result) % 360; // compensate the mirror
} else { // back-facing
result = (info.orientation - degrees + 360) % 360;
}
camera.setDisplayOrientation(result);
}
List<Size> mCameraSizes;
private byte[] dataL;
private byte[] dataR;
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, acquire the camera and tell it where
// to draw.
// int num = Camera.getNumberOfCameras ();
// Log.i("info", "Camera count : " + num );
// if(num < 2)
// {
// return;
// }
// mCamera = Camera.open(mCameraID);
mCamera = Camera.open(0);
if (mCamera == null) {
context.finish();
}
setCameraDisplayOrientation(context, 0, mCamera);
Camera.Parameters parameters = mCamera.getParameters();// 设置照片输出格式
parameters.setPictureFormat(PixelFormat.JPEG);
mCameraSizes = parameters.getSupportedPictureSizes();// 取得相机所支持多少图片大小的个数
String string = parameters.getFocusMode();
Log.i("info", string);
Size optimalSize = getOptimalPreviewSize(mCameraSizes, 1600, 960);
parameters.setPictureSize(640, 480);
parameters.setFocusMode(Parameters.FOCUS_MODE_AUTO);
// 给相机对象设置刚才设定的参数
mCamera.setParameters(parameters);
try {
mCamera.setPreviewDisplay(holder);
} catch (IOException exception) {
mCamera.release();
mCamera = null;
// TODO: add more exception handling logic here
}
}
/*
* 开始预览
*/
public void startPreview() {
if (mCamera != null) {
mCamera.startPreview();
}
}
/*
* 停止预览
*/
public void stopPreview() {
if (mCamera != null) {
mCamera.stopPreview();
}
}
/*
* 释放camera资源
*/
public void releaseCamera() {
if (mCamera != null) {
mCamera.stopPreview();
mCamera.cancelAutoFocus();
mCamera.release();
mCamera = null;
}
}
/**
* surface销毁时释放camera资源
*/
public void surfaceDestroyed(SurfaceHolder holder) {
// Surface will be destroyed when we return, so stop the preview.
// Because the CameraDevice object is not a shared resource, it's very
// important to release it when the activity is paused.
// context.si.setScreenDimension(false);
stopPreview();
releaseCamera();
}
/**
* 根据图片大小得到最适合的预览大小
*
* @param sizes
* @param w
* @param h
* @return
*/
private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
final double ASPECT_TOLERANCE = 0.05;
double targetRatio = (double) w / h;
if (sizes == null)
return null;
Size optimalSize = null;
double minDiff = 200;
int targetHeight = h;
// Try to find an size match aspect ratio and size
for (Size size : sizes) {
double ratio = (double) size.width / size.height;
if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE)
continue;
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
// Cannot find the one match the aspect ratio, ignore the requirement
if (optimalSize == null) {
minDiff = Double.MAX_VALUE;
for (Size size : sizes) {
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
}
return optimalSize;
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
Camera.Parameters parameters = mCamera.getParameters();
List<Size> sizes = parameters.getSupportedPreviewSizes();
Size optimalSize = getOptimalPreviewSize(sizes, w, h);
parameters.setPreviewSize(640, 480);
String s = String.format("surface w: %d h: %d", w, h);
mScreenWidth = w;
mScreenHeight = h;
Log.i("info", s);
// 创建用于预览合成的图片
mbmp_previewL = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);// 创建bitmap对象
mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
// mCamera.setParameters(parameters);
mCamera.startPreview();
}
public String filePath = null;
/*
* 保存图片
*/
public void savePicture() {
Date date = new Date();
SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");
String dateString = formatter.format(date);
String title = InterSurfaceView.CAMERA_PAHTARRAY[0] + "photo-"
+ dateString;
filePath = title + ".jps";
context.fileArray.add(filePath);
Bitmap bitl = BitmapFactory.decodeByteArray(dataL, 0, dataL.length);
Bitmap bitr = BitmapFactory.decodeByteArray(dataR, 0, dataR.length);
Bitmap b = Bitmap.createBitmap(bitl.getWidth() * 2, bitl.getHeight(),
Config.ARGB_8888);
Canvas c = new Canvas(b);
c.drawBitmap(bitl, 0, 0, null);
c.drawBitmap(bitr, bitl.getWidth(), 0, null);
// TODO Auto-generated method stub
// MPOFileStreamParser.encodeFile(filePath, dataL, dataR,
// new OnMPOWrittenListener() {
//
// @Override
// public void OnMPOWrittenCompleted() {
// // TODO Auto-generated method stub
// Message msg = new Message();
// msg.what = context.FINISH;
// context.mHandler.sendMessage(msg);
//
// }
// });
saveBitmap(b, filePath);
OperationFile.intTodb(getContext(), "image/jpeg", title, 0, filePath,
b.getByteCount());
Message msg = new Message();
stopPreview();
msg.what = context.FINISH;
context.mHandler.sendMessage(msg);
System.gc();
dataL = null;
dataR = null;
}
// 把bitmap保存成文件
public static void saveBitmap(Bitmap b, String filePath) {
File f = new File(filePath);
if (!f.getParentFile().exists()) {
f.mkdirs();
}
FileOutputStream fOut = null;
try {
fOut = new FileOutputStream(f);
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
b.compress(Bitmap.CompressFormat.JPEG, 100, fOut);
try {
fOut.flush();
} catch (IOException e) {
e.printStackTrace();
}
try {
fOut.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}