package com.minggo.pluto.util;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.Environment;
import android.os.ParcelFileDescriptor;
import android.provider.MediaStore;
import android.view.Display;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* 图片处理工具
* @author minggo
* @time 2014-12-2下午2:18:56
*/
@SuppressLint("NewApi")
public class PhotoUtil {
public static final int IMAGE_MAX_WIDTH = 300;
public static final int IMAGE_MAX_HEIGHT = 300;
/**
* sdcard 是否存在
*
* @return
*/
public static boolean isSDCardReady() {
return Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED);
}
public static String getFilePath(Activity activity, Uri uri) {
String[] proj = { MediaStore.Images.Media.DATA };
Cursor cursor = activity.managedQuery(uri, proj, null, null, null);
// 按我个人理解 这个是获得用户选择的图片的索引值
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
// 将光标移至开头 ,这个很重要,不小心很容易引起越界
cursor.moveToFirst();
// 最后根据索引值获取图片路径
String path = cursor.getString(column_index);
return path;
}
public static Bitmap getBitpMap(Context context, Uri uri, Display display) {
ParcelFileDescriptor pfd;
try {
pfd = context.getContentResolver().openFileDescriptor(uri, "r");
} catch (IOException ex) {
return null;
}
java.io.FileDescriptor fd = pfd.getFileDescriptor();
BitmapFactory.Options options = new BitmapFactory.Options();
// 先指定原始大小
options.inSampleSize = 1;
// 只进行大小判断
options.inJustDecodeBounds = true;
// 调用此方法得到options得到图片的大小
BitmapFactory.decodeFileDescriptor(fd, null, options);
// 我们的目标是在800pixel的画面上显示。
// 所以需要调用computeSampleSize得到图片缩放的比例
options.inSampleSize = computeSampleSize(options, display.getWidth(),
display.getHeight());
// OK,我们得到了缩放的比例,现在开始正式读入BitMap数据
options.inJustDecodeBounds = false;
options.inDither = false;
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
// 根据options参数,减少所需要的内存
Bitmap sourceBitmap = BitmapFactory.decodeFileDescriptor(fd, null,
options);
return sourceBitmap;
}
// 这个函数会对图片的大小进行判断,并得到合适的缩放比例,比如2即1/2,3即1/3
static int computeSampleSize(BitmapFactory.Options options,
int targetWindth, int targetHieght) {
int w = options.outWidth;
int h = options.outHeight;
int candidate = 0;
int candidateW = w / targetWindth;
int candidateH = h / targetHieght;
candidate = Math.max(candidateW, candidateH);
if (candidate == 0)
return 1;
if (candidate > 1) {
if ((w > targetWindth) && (w / candidate) < targetWindth)
candidate -= 1;
}
if (candidate > 1) {
if ((h > targetHieght) && (h / candidate) < targetHieght)
candidate -= 1;
}
return candidate;
}
/**
* Compress and resize the Image
*
* <br />
* 因为不论图片大小和尺寸如何, 都会对图片进行一次有损压缩, 所以本地压缩应该 考虑图片将会被二次压缩所造成的图片质量损耗
*
* @param quality
* 0~100,
* @return
* @throws IOException
*/
public static void compressImage(String filepath, int quality,
Display display) {
// 1. Calculate scale
int scale = 1;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filepath, options);
if (options.outWidth > IMAGE_MAX_WIDTH
|| options.outHeight > IMAGE_MAX_HEIGHT) {
scale = calculateInSampleSize(options, display.getWidth(),
display.getHeight());
}
options.inJustDecodeBounds = false;
options.inSampleSize = scale;
Bitmap bitmap = BitmapFactory.decodeFile(filepath, options);
Matrix matrix = new Matrix();
matrix.setRotate(readPictureDegree(filepath));
Bitmap saveBitmap = Bitmap.createBitmap(bitmap, 0, 0,
bitmap.getWidth(), bitmap.getHeight(), matrix, true);
writeToFile(filepath, saveBitmap, quality);
}
public static void compressImage(String savePath, String filepath,
int quality, Display display) {
int scale = 1;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filepath, options);
if (options.outWidth > IMAGE_MAX_WIDTH
|| options.outHeight > IMAGE_MAX_HEIGHT) {
scale = calculateInSampleSize(options, display.getWidth(),
display.getHeight());
}
options.inJustDecodeBounds = false;
options.inSampleSize = scale;
Bitmap bitmap = BitmapFactory.decodeFile(filepath, options);
Matrix matrix = new Matrix();
matrix.setRotate(readPictureDegree(filepath));
Bitmap saveBitmap = Bitmap.createBitmap(bitmap, 0, 0,
bitmap.getWidth(), bitmap.getHeight(), matrix, true);
writeToFile(savePath, saveBitmap, quality);
}
public static int calculateInSampleSize(BitmapFactory.Options options,
int reqWidth, int reqHeight) {
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
if (width > height) {
inSampleSize = Math.round((float) height / (float) reqWidth);
} else {
inSampleSize = Math.round((float) width / (float) reqHeight);
}
}
return inSampleSize + 1;
}
public static void writeToFile(String file, Bitmap bitmap, int quality) {
if (bitmap == null) {
return;
}
BufferedOutputStream bos = null;
try {
bos = new BufferedOutputStream(new FileOutputStream(file));
bitmap.compress(Bitmap.CompressFormat.JPEG, quality, bos); // PNG
} catch (IOException ioe) {
} finally {
try {
if (bos != null) {
bitmap.recycle();
bos.flush();
bos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static int readPictureDegree(String path) {
int degree = 0;
try {
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;
}
/**
* 转换图片成圆形
*
* @param bitmap
* 传入Bitmap对象
* @return
*/
public static Bitmap toRoundBitmap(Bitmap bitmap) {
//setup(bitmap);
//return bitmap;
int width = bitmap.getWidth();
int height = bitmap.getHeight();
float roundPx;
float left, top, right, bottom, dst_left, dst_top, dst_right, dst_bottom;
if (width <= height) {
roundPx = width / 2;
top = 0;
bottom = width;
left = 0;
right = width;
height = width;
dst_left = 0;
dst_top = 0;
dst_right = width;
dst_bottom = width;
} else {
roundPx = height / 2;
float clip = (width - height) / 2;
left = clip;
right = width - clip;
top = 0;
bottom = height;
width = height;
dst_left = 0;
dst_top = 0;
dst_right = height;
dst_bottom = height;
}
Bitmap output = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xff424242;
final Paint paint = new Paint();
final Rect src = new Rect((int) left, (int) top, (int) right,
(int) bottom);
final Rect dst = new Rect((int) dst_left, (int) dst_top,
(int) dst_right, (int) dst_bottom);
final RectF rectF = new RectF(dst);
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(bitmap, src, dst, paint);
return output;
}
public 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 index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(index);
}
} finally {
if (cursor != null)
cursor.close();
}
return null;
}
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is ExternalStorageProvider.
*/
public 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.
*/
public 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.
*/
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());
}
}