注意:三星手机中会出现照片旋转,进而引起返回数据时出现的activity生命周期被重置的问题,在清单文件中添加 一下代码就可以:
android:configChanges="orientation|keyboardHidden|screenSize"
/** * 从相册选择原生的照片(不裁切) */ public static void selectPhotoFromGallery(BrandCarBaseActivity activity, int requestCode) { Intent intent = new Intent(); intent.setAction(Intent.ACTION_PICK); //从所有图片中进行选择 intent.setType("image/*"); activity.startActivityForResult(intent, requestCode); } /** * 拍取照片不裁切 */ public static void selectPhotoFromTake(BrandCarBaseActivity activity, String fiePath, int requestCode) { Intent intent = new Intent(); //设置Action为拍照 intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE); //将拍取的照片保存到指定URI intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(fiePath))); activity.startActivityForResult(intent, requestCode); } /** * 采样率(等比)压缩 * 根据路径获得图片并压缩,返回bitmap用于显示 * * @param filePath 图片路径 * @param reqHeight 照片压缩后的height * @param reqWidth 照片压缩后的width * @return */ public static Bitmap getCompressBitmap(String filePath, int reqHeight, int reqWidth) { final BitmapFactory.Options options = new BitmapFactory.Options(); if (filePath != null) { options.inJustDecodeBounds = true; BitmapFactory.decodeFile(filePath, options); options.inSampleSize = caculateInSampleSize(options, reqHeight, reqWidth); options.inPreferredConfig = Bitmap.Config.RGB_565; options.inJustDecodeBounds = false; return rotateBitmapByDegree(BitmapFactory.decodeFile(filePath, options), getBitmapDegree(filePath)); } else { return null; } } /** * 采样率(等比)压缩 * * @param uri 图片uri * @param context * @return */ public static Bitmap getCompressBitmapFromUri(Context context, Uri uri, int reqHeight, int reqWidth) { return getCompressBitmap(getPathByUri(context, uri), reqHeight, reqWidth); } /** * 质量压缩并存储 * * @param bitmap * @param outFilePath 输出路径 * @param outSize 压缩后输出大小 kb */ public static void compressAndSaveImage(final Bitmap bitmap, final String outFilePath, final int outSize) { if (bitmap == null){ return; } new Thread(new Runnable() { @Override public void run() { ByteArrayOutputStream baos = new ByteArrayOutputStream(); int options = 100; //质量压缩方法,把压缩后的数据存放到baos中 (100表示不压缩,0表示压缩到最小) bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos); // 循环判断如果压缩后图片是否大于100kb,大于继续压缩 while (baos.toByteArray().length / 1024 > outSize) { // 重置baos即让下一次的写入覆盖之前的内容 baos.reset(); options -= 10; if (options < 0) { options = 0; } bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos); if (options == 0) { break; } } try { FileOutputStream fos = new FileOutputStream(new File(outFilePath)); fos.write(baos.toByteArray()); fos.flush(); fos.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }).start(); } /** * 质量压缩并存储 * * @param bitmap * @param outFilePath 输出路径 */ public static void saveImage(final Bitmap bitmap, final String outFilePath) { if (bitmap == null){ return; } new Thread(new Runnable() { @Override public void run() { try { int options = 100; FileOutputStream fos = new FileOutputStream(new File(outFilePath)); bitmap.compress(Bitmap.CompressFormat.JPEG, options, fos); fos.flush(); fos.close(); } catch (Exception e) { e.printStackTrace(); } } }).start(); } /** * 计算图片缩放值 * * @param options * @param reqWidth * @param reqHeight * @return */ public static int caculateInSampleSize(BitmapFactory.Options options, int reqHeight, int reqWidth) { final int width = options.outWidth; final int height = options.outHeight; int inSampleSize = 1; if (width > reqWidth || height > reqHeight) { final int heightRatio = Math.round((float) height / (float) reqHeight); final int widthRatio = Math.round((float) width / (float) reqWidth); inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio; } return inSampleSize; } public static String getPathByUri(Context context, Uri uri) { if ("content".equalsIgnoreCase(uri.getScheme())) { return getDataColumn(context, uri); } else { File file = new File(uri.getPath()); if (file.exists()) { return uri.getPath(); } } return null; } /** * uri路径查询字段 * * @param context * @param uri * @return */ public static String getDataColumn(Context context, Uri uri) { Cursor cursor = null; final String column = "_data"; final String[] projection = {column}; try { cursor = context.getContentResolver().query(uri, projection, null, null, null); if (cursor != null && cursor.moveToFirst()) { final int index = cursor.getColumnIndexOrThrow(column); return cursor.getString(index); } } finally { if (cursor != null) cursor.close(); } return null; } /** * 读取图片的旋转的角度 * * @param path 图片绝对路径 * @return 图片的旋转角度 */ public static int getBitmapDegree(String path) { int degree = 0; try { // 从指定路径下读取图片,并获取其EXIF信息 ExifInterface exifInterface = new ExifInterface(path); // 获取图片的旋转信息 int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); switch (orientation) { case ExifInterface.ORIENTATION_ROTATE_90: degree = 90; break; case ExifInterface.ORIENTATION_ROTATE_180: degree = 180; break; case ExifInterface.ORIENTATION_ROTATE_270: degree = 270; break; } } catch (IOException e) { e.printStackTrace(); } return degree; } public static Bitmap rotateBitmapByDegree(Bitmap bm, int degree) { Bitmap returnBm = null; try { // 将原始图片按照旋转矩阵进行旋转,并得到新的图片 if (bm != null) { // 根据旋转角度,生成旋转矩阵 Matrix matrix = new Matrix(); matrix.postRotate(degree); 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; }
获得相册或者拍照后数据处理方法:
//REQ_WIDTH和REQ_HEIGHT 是期望得到照片的大小
if (data.getData() == null) return; if (data.getData().getPath().startsWith("file")) { toastMsg(getResourceString(R.string.please_select_native_pic)); return; } Bitmap bm = getCompressBitmapFromUri(this, data.getData(), REQ_WIDTH, REQ_HEIGHT);