在最近的开发中,遇到一个需求,使用相机拍照,但是不能存储到本地,并上传到服务器,这边用到的服务器接受上传的是base64的,需要将图片转换成base64上传。接下来我们开始整。
CameraPreview
CameraPreview这个是自定义相机
参考https:blog.csdn.net/qq_28193010/article/details/102719369
在此基础上增加了切换前后摄像头的功能
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback{
private static final String TAG = "CameraPreview";
private final int CAMERA_FONT = Camera.CameraInfo.CAMERA_FACING_FRONT;//前置摄像头标记
private final int CAMERA_BACK = Camera.CameraInfo.CAMERA_FACING_BACK;//后置摄像头标记
/**
* open_camera 默认开启后置摄像头
* true 后置摄像头
* false 前置摄像头
*/
private boolean open_camera = true;
/**
* SurfaceHolder是控制surface的一个抽象接口,它能够控制surface的尺寸和格式,修改surface的像素,监视surface的变化等等
* 通过surfaceHolder可以将Camera和surface连接起来,当camera和surface连接后,camera获得的预览帧数据就可以通过surface显示在屏幕上了。
*/
private SurfaceHolder mHolder;
private Camera mCamera;
private int picWidth = 1920;
private int picHeight = 1080;
public CameraPreview(Context context,boolean camera) {
super(context);
this.open_camera = camera;
createCamera();
}
private void createCamera(){
// 打开相机,获取camera实例
mCamera = Camera.open(open_camera ? CAMERA_BACK: CAMERA_FONT);
//得到SurfaceHolder对象
mHolder = getHolder();
//添加回调,得到Surface的三个声明周期方法
mHolder.addCallback(this);
// deprecated setting, but required on Android versions prior to 3.0
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public Camera getCamera(){
if (mCamera == null)
createCamera();
return mCamera;
}
/**
* 在surface创建后立即被调用。
* 在开发自定义相机时,可以通过重载这个函数调用camera.open()、camera.setPreviewDisplay(),
* 来实现获取相机资源、连接camera和surface等操作。
* @param surfaceHolder
*/
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
if (mCamera == null)
createCamera();
try {
//设置预览方向
// mCamera.setDisplayOrientation(90);
//把这个预览效果展示在SurfaceView上面
mCamera.setPreviewDisplay(mHolder);
//开启预览效果
mCamera.startPreview();
} catch (IOException e) {
Log.d(TAG, "Error setting camera preview: " + e.getMessage());
}
}
/**
* 在surface发生format或size变化时调用。
* 在开发自定义相机时,可以通过重载这个函数调用camera.startPreview来开启相机预览,
* 使得camera预览帧数据可以传递给surface,从而实时显示相机预览图像。
* @param holder
* @param format
* @param width
* @param height
*/
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
if (holder.getSurface() == null) {
return;
}
// 停止预览,关闭camra底层的帧数据传递以及surface上的绘制。
mCamera.stopPreview();
//重新设置预览效果
try {
mCamera.setPreviewDisplay(mHolder);
} catch (IOException e) {
e.printStackTrace();
}
setCameraParams(mCamera,picWidth,picHeight);
// 开始预览,将camera底层硬件传来的预览帧数据显示在绑定的surface上。
mCamera.startPreview();
mCamera.autoFocus(new Camera.AutoFocusCallback() {
@Override
public void onAutoFocus(boolean success, Camera camera) {
if (success) {
camera.cancelAutoFocus();
}
}
});
}
public boolean getOpenCamera(){
return this.open_camera;
}
/**
* csutCamera 切换摄像头
*/
public void csutCamera(){
mCamera.stopPreview();//停止预览
mCamera.release();//释放摄像头
/**
* open_camera
* true 后置摄像头
* false 前置摄像头
*/
try {
mCamera = Camera.open(open_camera ? CAMERA_FONT : CAMERA_BACK);
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();//开启预览
open_camera = open_camera ? false : true;
Log.e(TAG, open_camera + "======");
} catch (IOException e) {
Log.e(TAG, "Error setting camera preview: " + e.getMessage());
}
setCameraParams(mCamera,picWidth,picHeight);
}
/**
* 在surface销毁之前被调用。在开发自定义相机时,可以通过重载这个函数调用camera.stopPreview(),
* camera.release()来实现停止相机预览及释放相机资源等操作。
* @param surfaceHolder
*/
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
if (mCamera != null) {
mCamera.stopPreview();
mCamera.setPreviewCallback(null);
mCamera.release(); // 释放Camera实例
mCamera = null;
}
}
// 设置相机参数:在surfaceChanged方法中执行mCamera.startPreview()前调用setCameraParams(mCamera, mScreenWidth, mScreenHeight); 就可以了
private void setCameraParams(Camera mCamera, int width, int height) {
Log.i(TAG, "setCameraParams width=" + width + " height=" + height);
Camera.Parameters parameters = mCamera.getParameters();
// 获取摄像头支持的PictureSize列表
List<Camera.Size> pictureSizeList = parameters.getSupportedPictureSizes();
Collections.sort(pictureSizeList, new Comparator<Camera.Size>() {
@Override
public int compare(Camera.Size o1, Camera.Size o2) {
return o2.width - o1.width;
}
});
for (Camera.Size size : pictureSizeList) {
Log.i(TAG, "pictureSizeList size.width=" + size.width + " size.height=" + size.height);
}
/** 从列表中选取合适的分辨率 */
Camera.Size picSize = getProperSize(pictureSizeList, ((float) height / width));
if (null == picSize) {
Log.i(TAG, "null == picSize");
picSize = parameters.getPictureSize();
}
Log.i(TAG, "picSize.width=" + picSize.width + " picSize.height=" + picSize.height);
// 根据选出的PictureSize重新设置SurfaceView大小
float w = picSize.width;
float h = picSize.height;
parameters.setPictureSize(picSize.width, picSize.height);
Log.d(TAG, "保存图片尺寸:width*height: "+ w + "*" + h);
//this.setLayoutParams(new FrameLayout.LayoutParams((int) (height * (h / w)), height));
// 获取摄像头支持的PreviewSize列表
List<Camera.Size> previewSizeList = parameters.getSupportedPreviewSizes();
Collections.sort(previewSizeList, new Comparator<Camera.Size>() {
@Override
public int compare(Camera.Size o1, Camera.Size o2) {
return o2.width - o1.width;
}
});
for (Camera.Size size : previewSizeList) {
Log.i(TAG, "previewSizeList size.width=" + size.width + " size.height=" + size.height);
}
Camera.Size preSize = getProperSize(previewSizeList, ((float) height) / width);
if (null != preSize) {
Log.i(TAG, "preSize.width=" + preSize.width + " preSize.height=" + preSize.height);
parameters.setPreviewSize(preSize.width, preSize.height);
}
Log.d(TAG, "预览图片尺寸:width*height: "+ preSize.width + "*" + preSize.height);
parameters.setJpegQuality(100); // 设置照片质量
// if (parameters.getSupportedFocusModes().contains(android.hardware.Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {
// parameters.setFocusMode(android.hardware.Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE); // 连续对焦模式
// }
// mCamera.cancelAutoFocus(); //自动对焦。
// 设置PreviewDisplay的方向,效果就是将捕获的画面旋转多少度显示
// TODO 这里直接设置90°不严谨,
// 具体见https://developer.android.com/reference/android/hardware/Camera.html#setPreviewDisplay%28android.view.SurfaceHolder%29
mCamera.setDisplayOrientation(90); // 不设置的话,将导致相机画面很奇怪
mCamera.setParameters(parameters);
}
/**
* 从列表中选取合适的分辨率
* 默认w:h = 4:3
* tip:这里的w对应屏幕的height, h对应屏幕的width
*/
private Camera.Size getProperSize(List<Camera.Size> pictureSizeList, float screenRatio) {
Log.i(TAG, "screenRatio=" + screenRatio);
Camera.Size result = null;
for (Camera.Size size : pictureSizeList) {
if (size.width == 1920 && size.height == 1080){
result = size;
break;
}
float currentRatio = ((float) size.width) / size.height;
if (currentRatio - screenRatio == 0 && size.width < 2500) {
result = size;
Log.d(TAG, "currentRatio - screenRatio == 0 : "+size.width);
break;
}
}
if (null == result) {
for (Camera.Size size : pictureSizeList) {
float curRatio = ((float) size.width) / size.height;
if (curRatio == 4f / 3 && size.width < 2500) {// 默认w:h = 4:3
result = size;
Log.d(TAG, "curRatio: "+curRatio);
break;
}
}
}
return result;
}
}
CustomTakePhotoActivity
CustomTakePhotoActivity是自定义相机预览页面,这里面将获取到的图片转换成了bitmap,再将bitmap转换成base64存储与缓存控件,其中有注释
public class CustomTakePhotoActivity extends BaseActivity {
private final String TAG="CustomTakePhotoActivity";
//存储缓存KEY
private final String CUSTOM_PHOTO="CUSTOM_PHOTO";
//存储缓存,是否拍摄背景图片
private final String IS_SET_BACKGROUND="IS_SET_BG";
//回调CODE
private final int CUSTOM_TAKE_RESULT=2023013101;
//裁剪完成回调CODE
private final int CUT_OVER_RESULT=200;
//失败回调CODE
private final int CUT_OVER_DEFAULT=500;
//是否重拍回调
private final int TAKE_FOR_RESULT_CODE=100;
//是否重拍KEY
private final String TAKE_AGAIN="CUT_PHOTO";
/**
* custom_takephoto_back 返回
*/
private LinearLayout mCustomTakephotoBack;
/**
* custom_takephoto_surface 预览图像
*/
private FrameLayout mCustomTakephotoSurface;
/**
* custom_takephoto_take 拍照
*/
private LinearLayout mCustomTakephotoTake;
/**
* custom_takephoto_cut 切换前后摄像头
*/
private LinearLayout mCustomTakephoto_Cut;
/**
* camera 声明相机对象
*/
private Camera mCamrea;
/**
* mCameraPreView 声明自定义相机
*/
private CameraPreview mCameraPreView;
/**
* openCamera 前后摄像头标记 默认开启后置摄像头
* true 后置摄像头
* false 前置摄像头
*/
private boolean openCamera=true;
/**
* isSetBg 是否设置背景图片,默认不是
* true 设置背景图片
* false 不是设置背景图片
*/
private boolean isSetBg=false;
/**
* mPreferences 缓存 存储图片数据
*/
private SharedPreferences mPreferences;
@Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_custom_takephoto_layout);
mPreferences=this.getSharedPreferences(CUSTOM_PHOTO, Activity.MODE_PRIVATE);
initView();
}
public void initView() {
mCustomTakephotoBack=findViewById(R.id.custom_takephoto_back);
mCustomTakephotoSurface=findViewById(R.id.custom_takephoto_surface);
mCustomTakephotoTake=findViewById(R.id.custom_takephoto_take);
mCustomTakephoto_Cut=findViewById(R.id.custom_takephoto_cut);
//初始化自定义相机
mCameraPreView=new CameraPreview(this, openCamera);
//获取相机对象
mCamrea=mCameraPreView.getCamera();
//添加预览页面
mCustomTakephotoSurface.addView(mCameraPreView);
//存储是否拍摄背景图片
boolean isSetBg=getIntent().getBooleanExtra("IsSetBg", false);
if(isSetBg) {
Editor editor=mPreferences.edit();
editor.putBoolean(IS_SET_BACKGROUND,isSetBg);
editor.putInt("SET_BG_WIDTH",640);
editor.putInt("SET_BG_HEIGHT",1130);
editor.commit();
}
mCustomTakephotoBack.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
CustomTakePhotoActivity.this.finish();
}
});
//点击拍照
mCustomTakephotoTake.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
//获取相机对象
mCamrea=mCameraPreView.getCamera();
//得到相机参数
Camera.Parameters parameters=mCamrea.getParameters();
//设置对焦模式,自动对焦
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
//设置图片格式
parameters.setPictureFormat(ImageFormat.JPEG);
//对焦成功后拍摄照片
mCamrea.autoFocus(new Camera.AutoFocusCallback() {
@Override
public void onAutoFocus(boolean success, Camera camera) {
// TODO Auto-generated method stub
if (success) {
mCamrea.takePicture(null, null,mPictureCallback);
}
}
});
}
});
}
/**
* 摄像头拍照回调
*/
private Camera.PictureCallback mPictureCallback =new Camera.PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
// TODO Auto-generated method stub
Log.d(TAG, "jepg:"+data.length/1024+"KB");
//转换为Bitmap
Bitmap bt=BitmapFactory.decodeByteArray(data, 0, data.length);
//转换为Base64,存储于缓存
Editor editor=mPreferences.edit();
editor.putString(CUSTOM_PHOTO,new BitmapToBase64().bitmapToBase64(bt));
editor.commit();
//存储缓存之后跳转预览页面
Intent intent=new Intent(CustomTakePhotoActivity.this,CustomShowImageActivity.class);
intent.putExtra(CUSTOM_PHOTO, openCamera);
startActivityForResult(intent,TAKE_FOR_RESULT_CODE);
}
};
/**
* TAKE_FOR_RESULT_CODE 回调判断是否重拍
* TAKE_AGAIN -1 重拍
* TAKE_AGAIN 0 裁剪完成
* TAKE_AGAIN 1 裁剪失败
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
if(requestCode==TAKE_FOR_RESULT_CODE) {
if(resultCode==RESULT_OK) {
int flag=data.getIntExtra(TAKE_AGAIN, -1);
if(flag==-1) {
//重拍
//清除缓存数据
Editor editor=mPreferences.edit();
editor.clear();
editor.commit();
//获取相机对象
mCamrea=mCameraPreView.getCamera();
//开启预览
mCamrea.startPreview();
}else if(flag==0 || flag == 1) {
//无需重拍,返回上一级判断是否裁剪成功
Intent intent=new Intent();
intent.putExtra("CUT_OVER",flag);
setResult(CUSTOM_TAKE_RESULT, intent);
finish();
}
}
}
}
}
CustomShowImageActivity
CustomShowImageActivity自定义的图片预览页面,确定或者重拍。这里特殊原因需要裁剪,因此我这里是确定之后跳转到裁剪页面的。
public class CustomShowImageActivity extends BaseActivity {
private final String TAG="CustomShowImageActivity";
//回调CODE
private final int CUSTOM_TAKE_RESULT=2023013101;
//缓存数据存储KEY
public static final String CUSTOM_PHOTO="CUSTOM_PHOTO";
//重拍回调
private final int TAKE_FOR_RESULT_CODE=100;
//重拍
private final String TAKE_AGAIN="TAKE_AGAIN";
/**
* custom_showimage_back 重拍
*/
private LinearLayout mCustomShowimageBack;
/**
* custom_showimage_submit 确定
*/
private LinearLayout mCustomShowimageSubmit;
/**
* custom_showimage_img 图片展示
*/
private ImageView mCustomShowimageImg;
/**
* mPreferences 获取缓存中图片数据
*/
private SharedPreferences mPreferences;
/**
* open_camera 判断前后摄像头 默认后置摄像头
*/
private boolean open_camera=true;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_custom_showimage_layout);
mPreferences=this.getSharedPreferences(CUSTOM_PHOTO, Activity.MODE_PRIVATE);
open_camera=getIntent().getBooleanExtra(CUSTOM_PHOTO,true);
initView();
}
public void initView() {
mCustomShowimageBack=findViewById(R.id.custom_showimage_back);
mCustomShowimageSubmit=findViewById(R.id.custom_showimage_submit);
mCustomShowimageImg=findViewById(R.id.custom_showimage_img);
//获取图片数据
String bitmap=mPreferences.getString(CUSTOM_PHOTO,"");
//将Base64转换为Bitmap
Bitmap bt=new BitmapToBase64().base64ToBitmap(bitmap);
//判断前后摄像头,进行处理
bt=new BitmapToBase64().converBimap(bt, open_camera);
//展示图片
mCustomShowimageImg.setImageBitmap(bt);
//重拍
mCustomShowimageBack.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent=new Intent();
intent.putExtra(TAKE_AGAIN,-1);
setResult(TAKE_FOR_RESULT_CODE,intent);
CustomShowImageActivity.this.finish();
}
});
//确定,跳转裁剪,因为之前已经存储过了,如果不重拍,到裁剪页面直接获取之前存储的图片数据,不再通过intent传递数据
mCustomShowimageSubmit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent=new Intent(CustomShowImageActivity.this,ClipPictureActivity.class);
intent.putExtra("CAMERA_PHOTO", 0);
startActivityForResult(intent, CUSTOM_TAKE_RESULT);
}
});
}
/**
* CUT_PHOTO -1 裁剪失败
* CUT_PHOTO 0 裁剪成功 不在此处判断是否裁剪成功,返回上一级
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
if(requestCode==CUSTOM_TAKE_RESULT) {
if(resultCode==RESULT_OK) {
int flag =data.getIntExtra("CUT_PHOTO",-1);
Intent intent=new Intent();
intent.putExtra("CUT_PHOTO",flag);
setResult(RESULT_OK, intent);
finish();
}
}
}
}
ClipPictureActivity
ClipPictureActivity,自定义裁剪,细节看注释
public class ClipPictureActivity extends Activity implements OnTouchListener,
OnClickListener {
//回调CODE
private final int CUSTOM_TAKE_RESULT=2023013101;
ImageView srcPic;
Button sure;
ClipView clipview;
private CommonUtil commonutil=new CommonUtil(this);
int reqwidth = 0;
int reqheight = 0;
// These matrices will be used to move and zoom image
Matrix matrix = new Matrix();
Matrix savedMatrix = new Matrix();
// We can be in one of these 3 states
static final int NONE = 0;
static final int DRAG = 1;
static final int ZOOM = 2;
private static final String TAG = "11";
int mode = NONE;
// Remember some things for zooming
PointF start = new PointF();
PointF mid = new PointF();
float oldDist = 1f;
//存储缓存KEY
private final String CUSTOM_PHOTO="CUSTOM_PHOTO";
//是否存储背景图片
private boolean isSetBg=false;
private SharedPreferences mPreferences;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mPreferences=this.getSharedPreferences(CUSTOM_PHOTO, Activity.MODE_PRIVATE);
isSetBg=mPreferences.getBoolean("IS_SET_BG", false);
if(isSetBg) {
reqwidth = mPreferences.getInt("SET_BG_WIDTH", 0);
reqheight = mPreferences.getInt("SET_BG_HEIGHT", 0);
}
String photoPath = null;
try {
photoPath = getIntent().getStringExtra("photoPath");
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
if (isSetBg && (0 != reqwidth && 0 != reqheight)) {
setContentView(R.layout.bgphotocrop);
} else {
setContentView(R.layout.photocrop);
}
Bitmap img=null;
// 设置要剪裁的图片
//判断是相机拍摄还是图库选择 0 相机 1 图库
int flag=getIntent().getIntExtra("CAMERA_PHOTO",1);
if(flag==0) {
//获取图片数据
String base=mPreferences.getString(CUSTOM_PHOTO, "");
//将Base64转换成bitmap
img =new BitmapToBase64().base64ToBitmap(base);
}else {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(photoPath, options);
options.inSampleSize = calculateInSampleSize(options, 600, 600);
options.inJustDecodeBounds = false;
img = BitmapFactory.decodeFile(photoPath, options);
}
if (img.getWidth() > img.getHeight()) {
img = rotateBitmapByDegree(img, 90);
}
srcPic = (ImageView) this.findViewById(R.id.src_pic);
srcPic.setImageBitmap(img);
if(img==null){
Intent idata = new Intent();
idata.putExtra("returnData", "文件格式不支持");
setResult(20141104, idata);
this.finish();
}else{
/* 这里就是绘制矩形区域 */
WindowManager wm = this.getWindowManager();
int width = wm.getDefaultDisplay().getWidth();
int height = wm.getDefaultDisplay().getHeight();
int w = img.getWidth();
int h = img.getWidth();
matrix.postTranslate((width - w) / 2, (height - h) / 2);
srcPic.setImageMatrix(matrix);
srcPic.setOnTouchListener(this);
sure = (Button) this.findViewById(R.id.sure);
sure.setOnClickListener(this);
}
}
public int calculateInSampleSize(BitmapFactory.Options options,
int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
// Calculate ratios of height and width to requested height and
// width
final int heightRatio = Math.round((float) height
/ (float) reqHeight);
final int widthRatio = Math.round((float) width / (float) reqWidth);
// Choose the smallest ratio as inSampleSize value, this will
// guarantee
// a final image with both dimensions larger than or equal to the
// requested height and width.
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
}
return inSampleSize;
}
/* 这里实现了多点触摸放大缩小,和单点移动图片的功能,参考了论坛的代码 */
public boolean onTouch(View v, MotionEvent event) {
ImageView view = (ImageView) v;
// Handle touch events here...
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
savedMatrix.set(matrix);
// 設置初始點位置
start.set(event.getX(), event.getY());
Log.d(TAG, "mode=DRAG");
mode = DRAG;
break;
case MotionEvent.ACTION_POINTER_DOWN:
oldDist = spacing(event);
Log.d(TAG, "oldDist=" + oldDist);
if (oldDist > 10f) {
savedMatrix.set(matrix);
midPoint(mid, event);
mode = ZOOM;
Log.d(TAG, "mode=ZOOM");
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
mode = NONE;
Log.d(TAG, "mode=NONE");
break;
case MotionEvent.ACTION_MOVE:
if (mode == DRAG) {
// ...
matrix.set(savedMatrix);
matrix.postTranslate(event.getX() - start.x, event.getY()
- start.y);
} else if (mode == ZOOM) {
float newDist = spacing(event);
Log.d(TAG, "newDist=" + newDist);
if (newDist > 10f) {
matrix.set(savedMatrix);
float scale = newDist / oldDist;
matrix.postScale(scale, scale, mid.x, mid.y);
}
}
break;
}
view.setImageMatrix(matrix);
return true; // indicate event was handled
}
/** Determine the space between the first two fingers */
private float spacing(MotionEvent event) {
float x = event.getX(0) - event.getX(1);
float y = event.getY(0) - event.getY(1);
return (float)Math.sqrt(x * x + y * y);
}
/** Calculate the mid point of the first two fingers */
private void midPoint(PointF point, MotionEvent event) {
float x = event.getX(0) + event.getX(1);
float y = event.getY(0) + event.getY(1);
point.set(x / 2, y / 2);
}
boolean isDoingtheJob = false;
/* 点击进入预览 */
public void onClick(View v) {
if (isDoingtheJob) {
return;
}
isDoingtheJob = true;
sure.setClickable(false);
try {
Bitmap fianBitmap = getBitmap();
// ByteArrayOutputStream baos = new ByteArrayOutputStream();
// fianBitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
// if(0!=reqwidth&&0!=reqheight){
// fianBitmap=bigBt(fianBitmap);
// }
// 压缩判断
// 图片允许最大空间 单位:KB
double maxSize = 150.00;
// 将bitmap放至数组中,意在bitmap的大小(与实际读取的原文件要大)
ByteArrayOutputStream baos = new ByteArrayOutputStream();
fianBitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
byte[] bb = baos.toByteArray();
// 将字节换成KB
double mid = bb.length / 1024;
// 判断bitmap占用空间是否大于允许最大空间 如果大于则压缩 小于则不压缩
if (mid > maxSize) {
// 获取bitmap大小 是允许最大大小的多少倍
double i = mid / maxSize;
// 开始压缩 此处用到平方根 将宽带和高度压缩掉对应的平方根倍
// (1.保持刻度和高度和原bitmap比率一致,压缩后也达到了最大大小占用空间的大小)
fianBitmap = HttpTool.zoomImage(fianBitmap,
fianBitmap.getWidth() / Math.sqrt(i),
fianBitmap.getHeight() / Math.sqrt(i));
}
Intent idata = new Intent();
if (Global.isDebug) {
System.out.println("reqwidth=" + reqwidth + ",reqheight="
+ reqheight + "-------------------->");
}
if () {
idata.putExtra("bitmap", BitmapUtils.Bitmap2Bytes(fianBitmap));
fianBitmap.recycle();
} else {
String base64 = bitmapToBase64(fianBitmap);
//idata.putExtra("bitmap", base64);
commonutil.doRememberAvatarBase64(base64);
fianBitmap.recycle();
idata.putExtra("CUT_PHOTO",0);
Editor editor=mPreferences.edit();
editor.clear();
editor.commit();
}
setResult(RESULT_OK, idata);
this.finish();
} catch (Exception e) {
isDoingtheJob = false;
sure.setClickable(true);
}
// startActivity(intent);
}
private Bitmap bigBt(Bitmap bitmap) {
if (Global.isDebug) {
System.out.println("((float)reqwidth)/cvrealwidth "
+ ((float) reqwidth) / cvrealwidth
+ "((float)reqwidth)/cvrealwidth" + ((float) reqheight)
/ cvrealheight);
}
Matrix matrix = new Matrix();
matrix.postScale(((float) reqwidth) / cvrealwidth, ((float) reqheight)
/ cvrealheight); // 长和宽放大缩小的比例
Bitmap resizeBmp = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
bitmap.getHeight(), matrix, true);
bitmap.recycle();
return resizeBmp;
}
private int cvrealwidth;
private int cvrealheight;
/* 获取矩形区域内的截图 */
private Bitmap getBitmap() {
getBarHeight();
Bitmap screenShoot = takeScreenShot();
if (0 != reqwidth && 0 != reqheight) {
clipview = (BGClipView) this.findViewById(R.id.clipview);
} else {
clipview = (HeaderClipView) this.findViewById(R.id.clipview);
}
int width = clipview.getWidth();
int height = clipview.getHeight();
cvrealwidth = height / 3;
cvrealheight = height / 3;
Bitmap finalBitmap;
if (0 != reqwidth && 0 != reqheight) {
finalBitmap = Bitmap.createBitmap(screenShoot,
(width - height / 3) / 2, height * 1 / 6 + titleBarHeight
+ statusBarHeight, height / 3, height * 2 / 3);
} else {
finalBitmap = Bitmap.createBitmap(screenShoot,
(width - height / 3) / 2, height / 3 + titleBarHeight
+ statusBarHeight, height / 3, height / 3);
}
screenShoot.recycle();
return finalBitmap;
}
int statusBarHeight = 0;
int titleBarHeight = 0;
private void getBarHeight() {
// 获取状态栏高度
Rect frame = new Rect();
this.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
statusBarHeight = frame.top;
int contenttop = this.getWindow()
.findViewById(Window.ID_ANDROID_CONTENT).getTop();
// statusBarHeight是上面所求的状态栏的高度
titleBarHeight = contenttop - statusBarHeight;
if (Global.isDebug) {
Log.v(TAG, "statusBarHeight = " + statusBarHeight
+ ", titleBarHeight = " + titleBarHeight);
}
}
// 获取Activity的截屏
private Bitmap takeScreenShot() {
View view = this.getWindow().getDecorView();
view.setDrawingCacheEnabled(true);
view.buildDrawingCache();
return view.getDrawingCache();
}
/**
* bitmap转为base64
*
* @param bitmap
* @return
*/
public String bitmapToBase64(Bitmap bitmap) {
String result = null;
ByteArrayOutputStream baos = null;
try {
if (bitmap != null) {
baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
baos.flush();
baos.close();
byte[] bitmapBytes = baos.toByteArray();
result = Base64.encodeToString(bitmapBytes, Base64.DEFAULT);
}
} catch (IOException e) {
// 解析出错
e.printStackTrace();
} finally {
try {
if (baos != null) {
baos.flush();
baos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return result;
}
public static Bitmap rotateBitmapByDegree(Bitmap bm, int degree) {
Bitmap returnBm = null;
// 根据旋转角度,生成旋转矩阵
Matrix matrix = new Matrix();
matrix.postRotate(degree);
try {
// 将原始图片按照旋转矩阵进行旋转,并得到新的图片
returnBm = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), matrix, true);
} catch (OutOfMemoryError e) {
}
if (returnBm == null) {
returnBm = bm;
}
if (bm != returnBm) {
bm.recycle();
}
return returnBm;
}
}
工具类
使用到的工具类,base64与bitmap之间的互相转换,以及bitmap图片旋转等操作
public class BitmapToBase64 {
private final String TAG="BitmapToBase64";
private ByteArrayOutputStream btOut;
/**
* Bitmap转换成Base64
* @param bt
* @return string
*/
public String bitmapToBase64(Bitmap bt) {
String result=null;
try {
if(bt!=null) {
btOut=new ByteArrayOutputStream();
bt.compress(Bitmap.CompressFormat.PNG, 100, btOut);
btOut.flush();
btOut.close();
byte[] btArray=btOut.toByteArray();
result=Base64.encodeToString(btArray,Base64.DEFAULT);
}
}catch(IOException e) {
Log.d(TAG, e.getMessage());
}finally {
try {
btOut.flush();
btOut.close();
} catch (IOException e2) {
// TODO: handle exception
}
}
return result;
}
/**
* Base64 转换成Bitmap
* @param base
* @return bitmap
*/
public Bitmap base64ToBitmap(String base) {
byte[] bytes=Base64.decode(base,Base64.DEFAULT);
Bitmap bt=BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
return bt;
}
/**
* Bitmap图像翻转
* @param bt
* @param camera
* true 后置摄像头 顺时针旋转90°
* false 前置摄像头 逆时针旋转90°+镜像水平翻转
* @return
*/
public Bitmap converBimap(Bitmap bt,boolean camera) {
int w=bt.getWidth();
int h=bt.getHeight();
//创建一个与原图大小一致的空白图
Bitmap bt1=Bitmap.createBitmap(w,h,Bitmap.Config.ARGB_8888);
Canvas canvas=new Canvas(bt1);
Matrix m=new Matrix();
if(camera) {
//后置摄像头,顺时针旋转90°
m.postRotate(90);
}else {
//前置摄像头 逆时针旋转90°+镜像水平翻转
m.postRotate(-90);
m.postScale(-1, 1);
}
Bitmap bt2=Bitmap.createBitmap(bt,0,0,w,h,m,true);
canvas.drawBitmap(bt2, new Rect(0, 0, bt2.getWidth(),bt2.getHeight()),new Rect(0,0,w,h),null);
return bt2;
}
}