package me.xiaopan.android.examples.activity.other;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import me.xiaopan.android.examples.MyBaseActivity;
import me.xiaopan.android.examples.R;
import me.xiaopan.easy.android.util.BitmapUtils;
import me.xiaopan.easy.android.util.FileUtils;
import me.xiaopan.easy.android.util.RectUtils;
import me.xiaopan.easy.android.util.ViewAnimationUtils;
import me.xiaopan.easy.android.util.camera.CameraManager;
import me.xiaopan.easy.android.util.camera.CameraManager.CamreaBeingUsedException;
import me.xiaopan.easy.android.util.camera.CameraOptimalSizeCalculator;
import me.xiaopan.easy.java.util.IOUtils;
import me.xiaopan.easy.java.util.StringUtils;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.graphics.Point;
import android.graphics.Rect;
import android.hardware.Camera;
import android.hardware.Camera.Size;
import android.net.Uri;
import android.os.Bundle;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.widget.Button;
import android.widget.ImageView;
/**
* 拍名片
*/
public class TakeBusinessCardActivity extends MyBaseActivity implements CameraManager.CameraCallback, Camera.PictureCallback{
/**
* 参数 - 可选的 - 字符串 - 名片保存路径,默认路径为SD中应用目录下cache/BusinessCardCache.jpeg
*/
public static final String PARAM_OPTIONAL_STRING_SAVE_PATH = "PARAM_OPTIONAL_STRING_SAVE_PATH";
/**
* 参数 - 可选的 - 整型 - 名片的输出宽度,名片的输出高度将以1.67:1的比例计算得出,默认宽高为648*388
*/
public static final String PARAM_OPTIONAL_INT_BUSINESS_CARD_WIDTH = "PARAM_OPTIONAL_INT_BUSINESS_CARD_WIDTH";
/**
* 返回 - 名片文件路径,默认路径为SD中应用目录下cache/BusinessCardCache.jpeg
*/
public static final String RETURN_BUSINESS_CARD_FILE_PATH = "RETURN_BUSINESS_CARD_FILE_PATH";
private boolean readTakePhotos;//准备拍照
private View cameraApertureView; //取景框视图
private View shutterButton; //快门按钮
private View userButton; //使用按钮
private View remakeButton; //重拍按钮
private Button flashModeButton; //闪光等控制按钮
private ImageView previewImage; //预览图
private SurfaceView surfaceView; //Surface视图
private File localCacheFile; //本地缓存文件
private Rect cameraApertureRect; //取景框的位置
private List<String> supportedFlashModes; //当前设备支持的闪光模式
private CameraManager cameraManager; //相机管理器
private int businessCardWidth = 648;
// private int businessCardHeight = 388;
@Override
public void onInitLayout(Bundle savedInstanceState) {
hiddenTitleBar();
hiddenStatusBar();
setContentView(R.layout.activity_take_business_card);
surfaceView = (SurfaceView) findViewById(R.id.surface_takeBusinessCard);
cameraApertureView = findViewById(R.id.view_takeBusinessCard_cameraAperture);
shutterButton = findViewById(R.id.button_takeBusinessCard_shutter);
userButton = findViewById(R.id.button_takeBusinessCard_use);
remakeButton = findViewById(R.id.button_takeBusinessCard_remake);
flashModeButton = (Button) findViewById(R.id.button_takeBusinessCard_flashMode);
previewImage = (ImageView) findViewById(R.id.image_takeBusinessCard_preview);
}
@Override
public void onInitListener(Bundle savedInstanceState) {
//点击显示界面的时候对焦
surfaceView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
cameraManager.autoFocus();
}
});
//按下拍摄按钮的时候会先对焦,对完焦再拍照
shutterButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
readTakePhotos = true;
cameraManager.autoFocus();
}
});
//点击闪光模式按钮,就按照支持的闪光模式依次更新
flashModeButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//新的闪光模式
String newFlashMode = supportedFlashModes.get((supportedFlashModes.indexOf(flashModeButton.getTag()) + 1) % supportedFlashModes.size());
setFlashModeImageButton(newFlashMode);
cameraManager.setFlashMode(newFlashMode);
}
});
//按钮使用按钮后,先对裁剪后的图片进行缩小,然后输出到本地缓存文件中
userButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Bitmap sourceBitmap = null;
Bitmap finalBitmap = null;
FileOutputStream fileOutputStream = null;
try {
/* 对裁剪后的图片进行缩小 */
sourceBitmap = BitmapFactory.decodeFile(localCacheFile.getPath());
finalBitmap = BitmapUtils.scaleByWidth(sourceBitmap, businessCardWidth);
sourceBitmap.recycle();
/* 将最终得到的图片输出到本地缓存文件中 */
if(!localCacheFile.exists()) localCacheFile.createNewFile();
fileOutputStream = new FileOutputStream(localCacheFile);
finalBitmap.compress(CompressFormat.JPEG, 90, fileOutputStream); //输出到本地缓存文件中
fileOutputStream.flush();
fileOutputStream.close();
finalBitmap.recycle();
/* 返回结果 */
getIntent().putExtra(RETURN_BUSINESS_CARD_FILE_PATH, localCacheFile.getPath());
setResult(RESULT_OK, getIntent());
finishActivity();
} catch (IOException e) {
e.printStackTrace();
if(finalBitmap != null){
finalBitmap.recycle();
}
if(sourceBitmap != null){
sourceBitmap.recycle();
}
if(fileOutputStream != null){
try {
fileOutputStream.flush();
} catch (IOException e1) {
e1.printStackTrace();
}
try {
fileOutputStream.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
toastS("保存失败,请重试");
}
}
});
//按钮重拍按钮后,先释放裁剪后的图片,然后隐藏使用、重拍按钮并显示快门按钮,最后在动画执行完毕之后将预览视图清空
remakeButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//渐隐快门按钮并渐现使用、重拍按钮
ViewAnimationUtils.visibleViewByAlpha(shutterButton);
ViewAnimationUtils.invisibleViewByAlpha(userButton);
ViewAnimationUtils.invisibleViewByAlpha(remakeButton, new AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {}
@Override
public void onAnimationRepeat(Animation animation) {}
@Override
public void onAnimationEnd(Animation animation) {
previewImage.setImageDrawable(null); //将预览视图清空
}
});
}
});
}
@Override
public void onInitData(Bundle savedInstanceState) {
/* 初始化本地保存文件 */
String savePath = getIntent().getStringExtra(PARAM_OPTIONAL_STRING_SAVE_PATH);
if(StringUtils.isNotEmpty(savePath)){
localCacheFile = new File(savePath);
}else{
localCacheFile = FileUtils.getFileFromDynamicCacheDir(getBaseContext(), "BusinessCardCache.jpeg");
}
if(!localCacheFile.exists()){
try {
localCacheFile.getParentFile().mkdirs();
localCacheFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
becauseExceptionFinishActivity();
}
}
/* 初始化名片的宽高 */
businessCardWidth = getIntent().getIntExtra(PARAM_OPTIONAL_INT_BUSINESS_CARD_WIDTH, 648);
// businessCardHeight = (int) (businessCardWidth/1.67);
/* 初始化相机关机器以及按钮 */
cameraManager = new CameraManager(this, surfaceView.getHolder(), this);
shutterButton.setVisibility(View.VISIBLE);
userButton.setVisibility(View.INVISIBLE);
remakeButton.setVisibility(View.INVISIBLE);
}
@Override
public void onResume() {
super.onResume();
try {
cameraManager.openBackCamera(true);
} catch (CamreaBeingUsedException e) {
e.printStackTrace();
toastL(R.string.toast_cameraOpenFailed);
becauseExceptionFinishActivity();
}
}
@Override
public void onPause() {
super.onPause();
cameraManager.release();
}
@Override
public void onDestroy() {
cameraManager = null;
super.onDestroy();
}
@Override
public void onInitCamera(Camera camera) {
Camera.Parameters cameraParameters = camera.getParameters();
/* 设置闪光模式 */
supportedFlashModes = new ArrayList<String>(3);
supportedFlashModes.add(Camera.Parameters.FLASH_MODE_OFF);
supportedFlashModes.add(Camera.Parameters.FLASH_MODE_ON);
if(cameraParameters.getSupportedFlashModes().contains(Camera.Parameters.FLASH_MODE_AUTO)){
cameraParameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);
supportedFlashModes.add(Camera.Parameters.FLASH_MODE_AUTO);
setFlashModeImageButton(Camera.Parameters.FLASH_MODE_AUTO);
}else{
cameraParameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
setFlashModeImageButton(Camera.Parameters.FLASH_MODE_OFF);
}
/* 设置预览和输出分辨率 */
Size[] optimalSizes = new CameraOptimalSizeCalculator().getPreviewAndPictureSize(surfaceView.getWidth(), surfaceView.getHeight(), cameraParameters.getSupportedPreviewSizes(), cameraParameters.getSupportedPictureSizes());
cameraParameters.setPreviewSize(optimalSizes[0].width, optimalSizes[0].height);
cameraParameters.setPictureSize(optimalSizes[1].width, optimalSizes[1].height);
camera.setParameters(cameraParameters);
}
@Override
public void onAutoFocus(boolean success, Camera camera) {
if(success){
if(readTakePhotos){
readTakePhotos = false;
cameraManager.takePicture(null, null, this);
}
}else{
cameraManager.autoFocus();
}
}
@Override
public void onStartPreview() {
cameraManager.autoFocus();
}
@Override
public void onStopPreview() {}
@Override
public void onPictureTaken(byte[] data, Camera camera) {
OutputStream fileOutputStream = null;
try {
/* 初始化源图,如果预览方向有旋转,就将图片转过来 */
Bitmap srcBitmap = null;
if(cameraManager.getDisplayOrientation() != 0){
Bitmap sourceBitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
srcBitmap = BitmapUtils.rotate(sourceBitmap, cameraManager.getDisplayOrientation());
sourceBitmap.recycle();
}else{
srcBitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
}
/* 根据取景框对原图进行截取,只要取景框内的部分 */
if(cameraApertureRect == null){
Rect cameraApertureViewInSurfaceViewRect = new Rect();
cameraApertureView.getGlobalVisibleRect(cameraApertureViewInSurfaceViewRect);
Camera.Size pictureSize = cameraManager.getCamera().getParameters().getPictureSize();
cameraApertureRect = RectUtils.mappingRect(cameraApertureViewInSurfaceViewRect, new Point(surfaceView.getWidth(), surfaceView.getHeight()), new Point(pictureSize.width, pictureSize.height), getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT);
}
Bitmap cutBitmap = Bitmap.createBitmap(srcBitmap, cameraApertureRect.left, cameraApertureRect.top, cameraApertureRect.width(), cameraApertureRect.height());
srcBitmap.recycle();
//将裁减后的图片输出到本地缓存文件中
if(!localCacheFile.exists()) localCacheFile.createNewFile();
fileOutputStream = IOUtils.openOutputStream(localCacheFile, false);
cutBitmap.compress(CompressFormat.JPEG, 100, fileOutputStream);
fileOutputStream.flush();
fileOutputStream.close();
//显示到预览图上
previewImage.setImageURI(Uri.fromFile(localCacheFile));
//渐隐快门按钮并渐现使用、重拍按钮
ViewAnimationUtils.invisibleViewByAlpha(shutterButton);
ViewAnimationUtils.visibleViewByAlpha(userButton);
ViewAnimationUtils.visibleViewByAlpha(remakeButton, new AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {}
@Override
public void onAnimationRepeat(Animation animation) {}
@Override
public void onAnimationEnd(Animation animation) {
cameraManager.startPreview();
}
});
} catch (Exception e) {
e.printStackTrace();
if(fileOutputStream != null){
try {
fileOutputStream.flush();
} catch (IOException e1) {
e1.printStackTrace();
}
try {
fileOutputStream.close();
} catch (IOException e1) {
e1.printStackTrace();
}
toastL("拍摄失败,请重拍");
}
}
}
/**
* 设置闪光模式切换按钮
* @param falshMode
*/
private void setFlashModeImageButton(String falshMode){
if(Camera.Parameters.FLASH_MODE_AUTO.equals(falshMode)){
flashModeButton.setCompoundDrawablesWithIntrinsicBounds(getDrawable(R.drawable.ic_flash_auto), null, null, null);
flashModeButton.setTag(Camera.Parameters.FLASH_MODE_AUTO);
flashModeButton.setText(R.string.base_auto);
}else if(Camera.Parameters.FLASH_MODE_OFF.equals(falshMode)){
flashModeButton.setCompoundDrawablesWithIntrinsicBounds(getDrawable(R.drawable.ic_flash_off), null, null, null);
flashModeButton.setTag(Camera.Parameters.FLASH_MODE_OFF);
flashModeButton.setText(R.string.base_close);
}else if(Camera.Parameters.FLASH_MODE_ON.equals(falshMode)){
flashModeButton.setCompoundDrawablesWithIntrinsicBounds(getDrawable(R.drawable.ic_flash_on), null, null, null);
flashModeButton.setTag(Camera.Parameters.FLASH_MODE_ON);
flashModeButton.setText(R.string.base_open);
}
}
}