content: package com.zhongou.utils;
  
  import android.app.Activity;
  import android.content.ContentUris;
  import android.content.Context;
  import android.content.Intent;
  import android.database.Cursor;
  import android.graphics.Bitmap;
  import android.graphics.BitmapFactory;
  import android.graphics.Matrix;
  import android.graphics.Point;
  import android.media.ThumbnailUtils;
  import android.net.Uri;
  import android.os.Build;
  import android.os.Environment;
  import android.provider.DocumentsContract;
  import android.provider.MediaStore;
  import android.util.Base64;
  import android.util.Log;
  import android.view.Display;
  import android.view.WindowManager;
  
  import com.zhongou.R;
  
  import java.io.ByteArrayOutputStream;
  import java.io.File;
  import java.io.FileOutputStream;
  import java.io.IOException;
  import java.text.SimpleDateFormat;
  import java.util.Date;
  
  /**
   *
   */
  public class ImageUtils {
  
      public static String convertBitmapToString(Bitmap bitmap) {
          ByteArrayOutputStream out = new ByteArrayOutputStream();
          bitmap.compress(Bitmap.CompressFormat.JPEG, 80, out);
  
          return Base64.encodeToString(out.toByteArray(), Base64.DEFAULT);
      }
  
      public static byte[] convertBitmapStringToByteArray(String bitmapByteString) {
          return Base64.decode(bitmapByteString, Base64.DEFAULT);
      }
  
      public static Bitmap rotatePicture(Context context, int rotation, byte[] data) {
          Bitmap bitmap = decodeSampledBitmapFromByte(context, data);
  
          if (rotation != 0) {
              Bitmap oldBitmap = bitmap;
  
              Matrix matrix = new Matrix();
              matrix.postRotate(rotation);
  
              bitmap = Bitmap.createBitmap(
                      oldBitmap, 0, 0, oldBitmap.getWidth(), oldBitmap.getHeight(), matrix, false
              );
  
              oldBitmap.recycle();
          }
  
          return bitmap;
      }
  
      public static Uri savePicture(Context context, Bitmap bitmap) {
          int cropHeight;
          if (bitmap.getHeight() > bitmap.getWidth()) {
  
              cropHeight = bitmap.getWidth();
          } else {
  
              cropHeight = bitmap.getHeight();
          }
  
          bitmap = ThumbnailUtils.extractThumbnail(bitmap, cropHeight, cropHeight, ThumbnailUtils.OPTIONS_RECYCLE_INPUT);
  
          File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), context.getString(R.string.app_name));
  
          if (!mediaStorageDir.exists()) {
              if (!mediaStorageDir.mkdirs()) {
                  return null;
              }
          }
  
          String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
          //最终保存路径：
          File mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_" + timeStamp + ".jpg");
          Log.d("SJY", "ImageUtils--picpath=" + mediaFile);
          // Saving the bitmap
          try {
              ByteArrayOutputStream out = new ByteArrayOutputStream();
              bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
  
              FileOutputStream stream = new FileOutputStream(mediaFile);
              stream.write(out.toByteArray());
              stream.close();
  
          } catch (IOException exception) {
              exception.printStackTrace();
          }
  
          // Mediascanner need to scan for the image saved
          Intent mediaScannerIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
          Uri fileContentUri = Uri.fromFile(mediaFile);
          Log.d("SJY", "ImageUtils--picpathURI=" + fileContentUri.toString());
          mediaScannerIntent.setData(fileContentUri);
          context.sendBroadcast(mediaScannerIntent);
  
          return fileContentUri;
      }
  
      public static Bitmap decodeSampledBitmapFromPath(String path, int reqWidth, int reqHeight) {
          final BitmapFactory.Options options = new BitmapFactory.Options();
          options.inJustDecodeBounds = true;
          options.inMutable = true;
          options.inBitmap = BitmapFactory.decodeFile(path, options);
  
          options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
  
          options.inJustDecodeBounds = false;
          options.inPurgeable = true;
          options.inInputShareable = true;
  
          return BitmapFactory.decodeFile(path, options);
      }
  
      /**
       * Decode and sample down a bitmap from a byte stream
       */
      public static Bitmap decodeSampledBitmapFromByte(Context context, byte[] bitmapBytes) {
          Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
  
          int reqWidth, reqHeight;
          Point point = new Point();
  
          if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
              display.getSize(point);
              reqWidth = point.x;
              reqHeight = point.y;
          } else {
              reqWidth = display.getWidth();
              reqHeight = display.getHeight();
          }
  
  
          final BitmapFactory.Options options = new BitmapFactory.Options();
          options.inJustDecodeBounds = true;
          options.inMutable = true;
          options.inBitmap = BitmapFactory.decodeByteArray(bitmapBytes, 0, bitmapBytes.length, options);
  
          // Calculate inSampleSize
          options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
  
          // Decode bitmap with inSampleSize set
          options.inJustDecodeBounds = false; // If set to true, the decoder will return null (no bitmap), but the out... fields will still be set, allowing the caller to query the bitmap without having to allocate the memory for its pixels.
          options.inPurgeable = true;         // Tell to gc that whether it needs free memory, the Bitmap can be cleared
          options.inInputShareable = true;    // Which kind of reference will be used to recover the Bitmap data after being clear, when it will be used in the future
  
          return BitmapFactory.decodeByteArray(bitmapBytes, 0, bitmapBytes.length, options);
      }
  
      /**
       * Calculate an inSampleSize for use in a {@link BitmapFactory.Options} object when decoding
       * bitmaps using the decode* methods from {@link BitmapFactory}. This implementation calculates
       * the closest inSampleSize that is a power of 2 and will result in the final decoded bitmap
       * having a width and height equal to or larger than the requested width and height
       * <p>
       * The function rounds up the sample size to a power of 2 or multiple
       * of 8 because BitmapFactory only honors sample size this way.
       * For example, BitmapFactory downsamples an image by 2 even though the
       * request is 3. So we round up the sample size to avoid OOM.
       */
      public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
          int initialInSampleSize = computeInitialSampleSize(options, reqWidth, reqHeight);
  
          int roundedInSampleSize;
          if (initialInSampleSize <= 8) {
              roundedInSampleSize = 1;
              while (roundedInSampleSize < initialInSampleSize) {
                  // Shift one bit to left
                  roundedInSampleSize <<= 1;
              }
          } else {
              roundedInSampleSize = (initialInSampleSize + 7) / 8 * 8;
          }
  
          return roundedInSampleSize;
      }
  
      private static int computeInitialSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
          // Raw height and width of image
          final double height = options.outHeight;
          final double width = options.outWidth;
  
          final long maxNumOfPixels = reqWidth * reqHeight;
          final int minSideLength = Math.min(reqHeight, reqWidth);
  
          int lowerBound = (maxNumOfPixels < 0) ? 1 :
                  (int) Math.ceil(Math.sqrt(width * height / maxNumOfPixels));
          int upperBound = (minSideLength < 0) ? 128 :
                  (int) Math.min(Math.floor(width / minSideLength),
                          Math.floor(height / minSideLength));
  
          if (upperBound < lowerBound) {
              // return the larger one when there is no overlapping zone.
              return lowerBound;
          }
  
          if (maxNumOfPixels < 0 && minSideLength < 0) {
              return 1;
          } else if (minSideLength < 0) {
              return lowerBound;
          } else {
              return upperBound;
          }
      }
      /**
       * 根据Uri获取图片绝对路径，解决Android4.4以上版本Uri转换
       * @param imageUri
       * @author yaoxing
       * @date 2014-10-12
       */
  
      public static String getImageAbsolutePath(Activity context, Uri imageUri) {
          if (context == null || imageUri == null)
              return null;
          if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && DocumentsContract.isDocumentUri(context, imageUri)) {
              if (isExternalStorageDocument(imageUri)) {
                  String docId = DocumentsContract.getDocumentId(imageUri);
                  String[] split = docId.split(":");
                  String type = split[0];
                  if ("primary".equalsIgnoreCase(type)) {
                      return Environment.getExternalStorageDirectory() + "/" + split[1];
                  }
              } else if (isDownloadsDocument(imageUri)) {
                  String id = DocumentsContract.getDocumentId(imageUri);
                  Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
                  return getDataColumn(context, contentUri, null, null);
              } else if (isMediaDocument(imageUri)) {
                  String docId = DocumentsContract.getDocumentId(imageUri);
                  String[] split = docId.split(":");
                  String type = split[0];
                  Uri contentUri = null;
                  if ("image".equals(type)) {
                      contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                  } else if ("video".equals(type)) {
                      contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                  } else if ("audio".equals(type)) {
                      contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                  }
                  String selection = MediaStore.Images.Media._ID + "=?";
                  String[] selectionArgs = new String[] { split[1] };
                  return getDataColumn(context, contentUri, selection, selectionArgs);
              }
          } // MediaStore (and general)
          else if ("content".equalsIgnoreCase(imageUri.getScheme())) {
              // Return the remote address
              if (isGooglePhotosUri(imageUri))
                  return imageUri.getLastPathSegment();
              return getDataColumn(context, imageUri, null, null);
          }
          // File
          else if ("file".equalsIgnoreCase(imageUri.getScheme())) {
              return imageUri.getPath();
          }
          return null;
      }
  
      public static boolean isExternalStorageDocument(Uri uri) {
          return "com.android.externalstorage.documents".equals(uri.getAuthority());
      }
  
      public static boolean isDownloadsDocument(Uri uri) {
          return "com.android.providers.downloads.documents".equals(uri.getAuthority());
      }
  
      public static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {
          Cursor cursor = null;
          String column = MediaStore.Images.Media.DATA;
          String[] projection = { column };
          try {
              cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
              if (cursor != null && cursor.moveToFirst()) {
                  int index = cursor.getColumnIndexOrThrow(column);
                  return cursor.getString(index);
              }
          } finally {
              if (cursor != null)
                  cursor.close();
          }
          return null;
      }
      public static boolean isMediaDocument(Uri uri) {
          return "com.android.providers.media.documents".equals(uri.getAuthority());
      }
  
      /**
       * @param uri The Uri to check.
       * @return Whether the Uri authority is Google Photos.
       */
      public static boolean isGooglePhotosUri(Uri uri) {
          return "com.google.android.apps.photos.content".equals(uri.getAuthority());
      }
  }
  