|
|
@@ -0,0 +1,282 @@ |
|
|
|
package com.nsgk.ruralWeb.utils; |
|
|
|
|
|
|
|
import android.annotation.SuppressLint; |
|
|
|
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.net.Uri; |
|
|
|
import android.os.Build; |
|
|
|
import android.os.Environment; |
|
|
|
import android.provider.DocumentsContract; |
|
|
|
import android.provider.MediaStore; |
|
|
|
|
|
|
|
import java.io.ByteArrayInputStream; |
|
|
|
import java.io.ByteArrayOutputStream; |
|
|
|
import java.io.FileNotFoundException; |
|
|
|
import java.io.IOException; |
|
|
|
import java.io.InputStream; |
|
|
|
|
|
|
|
public class PhotoUtils { |
|
|
|
private static final String TAG = "PhotoUtils"; |
|
|
|
|
|
|
|
/** |
|
|
|
* @param activity 当前activity |
|
|
|
* @param imageUri 拍照后照片存储路径 |
|
|
|
* @param requestCode 调用系统相机请求码 |
|
|
|
*/ |
|
|
|
public static void takePicture(Activity activity, Uri imageUri, int requestCode) { |
|
|
|
//调用系统相机 |
|
|
|
Intent intentCamera = new Intent(); |
|
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { |
|
|
|
intentCamera.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); //添加这一句表示对目标应用临时授权该Uri所代表的文件 |
|
|
|
} |
|
|
|
intentCamera.setAction(MediaStore.ACTION_IMAGE_CAPTURE); |
|
|
|
//将拍照结果保存至photo_file的Uri中,不保留在相册中 |
|
|
|
intentCamera.putExtra(MediaStore.EXTRA_OUTPUT, imageUri); |
|
|
|
if (activity != null) { |
|
|
|
activity.startActivityForResult(intentCamera, requestCode); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* @param activity 当前activity |
|
|
|
* @param requestCode 打开相册的请求码 |
|
|
|
*/ |
|
|
|
public static void openPic(Activity activity, int requestCode) { |
|
|
|
Intent photoPickerIntent = new Intent(Intent.ACTION_GET_CONTENT); |
|
|
|
photoPickerIntent.setType("image/*"); |
|
|
|
activity.startActivityForResult(photoPickerIntent, requestCode); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* @param activity 当前activity |
|
|
|
* @param orgUri 剪裁原图的Uri |
|
|
|
* @param desUri 剪裁后的图片的Uri |
|
|
|
* @param aspectX X方向的比例 |
|
|
|
* @param aspectY Y方向的比例 |
|
|
|
* @param width 剪裁图片的宽度 |
|
|
|
* @param height 剪裁图片高度 |
|
|
|
* @param requestCode 剪裁图片的请求码 |
|
|
|
*/ |
|
|
|
public static void cropImageUri(Activity activity, Uri orgUri, Uri desUri, int aspectX, int aspectY, int width, int height, int requestCode) { |
|
|
|
Intent intent = new Intent("com.android.camera.action.CROP"); |
|
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { |
|
|
|
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); |
|
|
|
} |
|
|
|
intent.setDataAndType(orgUri, "image/*"); |
|
|
|
intent.putExtra("crop", "true"); |
|
|
|
intent.putExtra("aspectX", aspectX); |
|
|
|
intent.putExtra("aspectY", aspectY); |
|
|
|
intent.putExtra("outputX", width); |
|
|
|
intent.putExtra("outputY", height); |
|
|
|
intent.putExtra("scale", true); |
|
|
|
//将剪切的图片保存到目标Uri中 |
|
|
|
intent.putExtra(MediaStore.EXTRA_OUTPUT, desUri); |
|
|
|
intent.putExtra("return-data", false); |
|
|
|
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString()); |
|
|
|
intent.putExtra("noFaceDetection", true); |
|
|
|
activity.startActivityForResult(intent, requestCode); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 读取uri所在的图片 |
|
|
|
* |
|
|
|
* @param uri 图片对应的Uri |
|
|
|
* @param mContext 上下文对象 |
|
|
|
* @return 获取图像的Bitmap |
|
|
|
*/ |
|
|
|
public static Bitmap getBitmapFromUri(Uri uri, Context mContext) { |
|
|
|
try { |
|
|
|
// Bitmap bitmap = MediaStore.Images.Media.getBitmap(mContext.getContentResolver(), uri); |
|
|
|
Bitmap bitmapFormUri = getBitmapFormUri(mContext, uri); |
|
|
|
return bitmapFormUri; |
|
|
|
} catch (Exception e) { |
|
|
|
e.printStackTrace(); |
|
|
|
return null; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 通过uri获取图片并进行压缩 |
|
|
|
* |
|
|
|
* @param uri |
|
|
|
*/ |
|
|
|
public static Bitmap getBitmapFormUri(Context ac, Uri uri) throws FileNotFoundException, IOException { |
|
|
|
InputStream input = ac.getContentResolver().openInputStream(uri); |
|
|
|
BitmapFactory.Options onlyBoundsOptions = new BitmapFactory.Options(); |
|
|
|
onlyBoundsOptions.inJustDecodeBounds = true; |
|
|
|
onlyBoundsOptions.inDither = true;//optional |
|
|
|
onlyBoundsOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;//optional |
|
|
|
BitmapFactory.decodeStream(input, null, onlyBoundsOptions); |
|
|
|
input.close(); |
|
|
|
int originalWidth = onlyBoundsOptions.outWidth; |
|
|
|
int originalHeight = onlyBoundsOptions.outHeight; |
|
|
|
if ((originalWidth == -1) || (originalHeight == -1)) { |
|
|
|
return null; |
|
|
|
} |
|
|
|
//图片分辨率以480x800为标准 |
|
|
|
float hh = 800f;//这里设置高度为800f |
|
|
|
float ww = 480f;//这里设置宽度为480f |
|
|
|
//缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可 |
|
|
|
int be = 1;//be=1表示不缩放 |
|
|
|
if (originalWidth > originalHeight && originalWidth > ww) {//如果宽度大的话根据宽度固定大小缩放 |
|
|
|
be = (int) (originalWidth / ww); |
|
|
|
} else if (originalWidth < originalHeight && originalHeight > hh) {//如果高度高的话根据宽度固定大小缩放 |
|
|
|
be = (int) (originalHeight / hh); |
|
|
|
} |
|
|
|
if (be <= 0) { |
|
|
|
be = 1; |
|
|
|
} |
|
|
|
//比例压缩 |
|
|
|
BitmapFactory.Options bitmapOptions = new BitmapFactory.Options(); |
|
|
|
bitmapOptions.inSampleSize = be;//设置缩放比例 |
|
|
|
bitmapOptions.inDither = true;//optional |
|
|
|
bitmapOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;//optional |
|
|
|
input = ac.getContentResolver().openInputStream(uri); |
|
|
|
Bitmap bitmap = BitmapFactory.decodeStream(input, null, bitmapOptions); |
|
|
|
input.close(); |
|
|
|
return compressImage(bitmap);//再进行质量压缩 |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 质量压缩方法 |
|
|
|
* |
|
|
|
* @param image |
|
|
|
* @return |
|
|
|
*/ |
|
|
|
public static Bitmap compressImage(Bitmap image) { |
|
|
|
ByteArrayOutputStream baos = new ByteArrayOutputStream(); |
|
|
|
image.compress(Bitmap.CompressFormat.JPEG, 100, baos);//质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中 |
|
|
|
int options = 100; |
|
|
|
while (baos.toByteArray().length / 1024 > 100) { //循环判断如果压缩后图片是否大于100kb,大于继续压缩 |
|
|
|
baos.reset();//重置baos即清空baos |
|
|
|
//第一个参数 :图片格式 ,第二个参数: 图片质量,100为最高,0为最差 ,第三个参数:保存压缩后的数据的流 |
|
|
|
image.compress(Bitmap.CompressFormat.JPEG, options, baos);//这里压缩options%,把压缩后的数据存放到baos中 |
|
|
|
options -= 10;//每次都减少10 |
|
|
|
} |
|
|
|
ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());//把压缩后的数据baos存放到ByteArrayInputStream中 |
|
|
|
Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);//把ByteArrayInputStream数据生成图片 |
|
|
|
return bitmap; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* @param context 上下文对象 |
|
|
|
* @param uri 当前相册照片的Uri |
|
|
|
* @return 解析后的Uri对应的String |
|
|
|
*/ |
|
|
|
@SuppressLint("NewApi") |
|
|
|
public static String getPath(final Context context, final Uri uri) { |
|
|
|
|
|
|
|
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; |
|
|
|
String pathHead = "file:///"; |
|
|
|
// DocumentProvider |
|
|
|
if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) { |
|
|
|
// ExternalStorageProvider |
|
|
|
if (isExternalStorageDocument(uri)) { |
|
|
|
final String docId = DocumentsContract.getDocumentId(uri); |
|
|
|
final String[] split = docId.split(":"); |
|
|
|
final String type = split[0]; |
|
|
|
if ("primary".equalsIgnoreCase(type)) { |
|
|
|
return pathHead + Environment.getExternalStorageDirectory() + "/" + split[1]; |
|
|
|
} |
|
|
|
} |
|
|
|
// DownloadsProvider |
|
|
|
else if (isDownloadsDocument(uri)) { |
|
|
|
|
|
|
|
final String id = DocumentsContract.getDocumentId(uri); |
|
|
|
|
|
|
|
final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)); |
|
|
|
|
|
|
|
return pathHead + getDataColumn(context, contentUri, null, null); |
|
|
|
} |
|
|
|
// MediaProvider |
|
|
|
else if (isMediaDocument(uri)) { |
|
|
|
final String docId = DocumentsContract.getDocumentId(uri); |
|
|
|
final String[] split = docId.split(":"); |
|
|
|
final 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; |
|
|
|
} |
|
|
|
|
|
|
|
final String selection = "_id=?"; |
|
|
|
final String[] selectionArgs = new String[]{split[1]}; |
|
|
|
|
|
|
|
return pathHead + getDataColumn(context, contentUri, selection, selectionArgs); |
|
|
|
} |
|
|
|
} |
|
|
|
// MediaStore (and general) |
|
|
|
else if ("content".equalsIgnoreCase(uri.getScheme())) { |
|
|
|
return pathHead + getDataColumn(context, uri, null, null); |
|
|
|
} |
|
|
|
// File |
|
|
|
else if ("file".equalsIgnoreCase(uri.getScheme())) { |
|
|
|
return pathHead + uri.getPath(); |
|
|
|
} |
|
|
|
return null; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Get the value of the data column for this Uri. This is useful for |
|
|
|
* MediaStore Uris, and other file-based ContentProviders. |
|
|
|
* |
|
|
|
* @param context The context. |
|
|
|
* @param uri The Uri to query. |
|
|
|
* @param selection (Optional) Filter used in the query. |
|
|
|
* @param selectionArgs (Optional) Selection arguments used in the query. |
|
|
|
* @return The value of the _data column, which is typically a file path. |
|
|
|
*/ |
|
|
|
private static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) { |
|
|
|
|
|
|
|
Cursor cursor = null; |
|
|
|
final String column = "_data"; |
|
|
|
final String[] projection = {column}; |
|
|
|
try { |
|
|
|
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null); |
|
|
|
if (cursor != null && cursor.moveToFirst()) { |
|
|
|
final int column_index = cursor.getColumnIndexOrThrow(column); |
|
|
|
return cursor.getString(column_index); |
|
|
|
} |
|
|
|
} finally { |
|
|
|
if (cursor != null) { |
|
|
|
cursor.close(); |
|
|
|
} |
|
|
|
} |
|
|
|
return null; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* @param uri The Uri to check. |
|
|
|
* @return Whether the Uri authority is ExternalStorageProvider. |
|
|
|
*/ |
|
|
|
private static boolean isExternalStorageDocument(Uri uri) { |
|
|
|
return "com.android.externalstorage.documents".equals(uri.getAuthority()); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* @param uri The Uri to check. |
|
|
|
* @return Whether the Uri authority is DownloadsProvider. |
|
|
|
*/ |
|
|
|
private static boolean isDownloadsDocument(Uri uri) { |
|
|
|
return "com.android.providers.downloads.documents".equals(uri.getAuthority()); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* @param uri The Uri to check. |
|
|
|
* @return Whether the Uri authority is MediaProvider. |
|
|
|
*/ |
|
|
|
private static boolean isMediaDocument(Uri uri) { |
|
|
|
return "com.android.providers.media.documents".equals(uri.getAuthority()); |
|
|
|
} |
|
|
|
|
|
|
|
} |