package com.wisedu.scc.love.utils;
import android.content.Context;
import android.content.CursorLoader;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Rect;
import android.media.ExifInterface;
import android.net.Uri;
import android.provider.MediaStore;
import android.util.Log;
import com.wisedu.scc.love.utils.IOUtil;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
/**
* 解码工具
*/
public class DecodeUtil {
public static final int MAX_WIDTH_SIZE = 800;
public static final int MAX_HEIGHT_SIZE = 1280;
/**
* 获取宽度
* @param object
* @return
*/
public static int getWidth(Object object) {
try {
int width = ((Integer) reflect(object, "getWidth", new Object[0]))
.intValue();
return width;
} catch (Exception e) {
e.printStackTrace();
}
return 0;
}
/**
* 获取高度
* @param object
* @return
*/
public static int getHeight(Object object) {
try {
int height = ((Integer) reflect(object, "getHeight", new Object[0]))
.intValue();
return height;
} catch (Exception e) {
e.printStackTrace();
}
return 0;
}
/**
* 解码对象
* @param paramObject
* @param paramRect
* @param paramOptions
* @return
*/
public static Bitmap decodeRegion(Object paramObject, Rect paramRect,
BitmapFactory.Options paramOptions) {
return (Bitmap) reflect(paramObject, "decodeRegion", new Class[] {
Rect.class, BitmapFactory.Options.class }, new Object[] {
paramRect, paramOptions });
}
public static Object reflect(Object object, String method,
Object[] paramValue) {
Class<?>[] paramType = new Class<?>[paramValue.length];
int i = 0;
int j = paramValue.length;
while (i < j) {
paramType[i] = paramValue[i].getClass();
++i;
}
return reflect(object, method, paramType, paramValue);
}
public static Object reflect(Object object, String method,
Class<?>[] paramType, Object[] paramValue) {
try {
Object ret = object.getClass().getMethod(method, paramType)
.invoke(object, paramValue);
return ret;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 解码Uri对象
* @param context
* @param uri
* @param maxW
* @param maxH
* @return
*/
public static Bitmap decode(Context context, Uri uri, int maxW, int maxH) {
InputStream stream = openInputStream(context, uri);
if (null == stream) {
return null;
}
maxW = maxW > MAX_WIDTH_SIZE ? MAX_WIDTH_SIZE : maxW;
maxH = maxH > MAX_HEIGHT_SIZE ? MAX_HEIGHT_SIZE : maxH;
Bitmap bitmap = null;
int[] imageSize = new int[2];
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
boolean decoded = decodeImageBounds(stream, imageSize, options);
int orientation = getExifOrientation(uri, options.outMimeType);
IOUtil.closeSilently(stream);
Log.v("dsd", "decode orientation:" + orientation + " decoded:"
+ decoded);
if (decoded) {
int sampleSize = computeSampleSize(imageSize[0], imageSize[1],
(int) (maxW * 1.2D), (int) (maxH * 1.2D), orientation);
options = getDefaultOptions();
float maxSampleW = maxW * 1.5F;
float maxSampleH = maxH * 1.5F;
if ((imageSize[1] < maxSampleW + 100.0F)
&& (imageSize[1] < maxSampleH)) {
sampleSize = 1;
}
options.inSampleSize = sampleSize;
bitmap = decodeBitmap(context, uri, options, maxW, maxH,
orientation, 0);
}
return bitmap;
}
/**
* 解码Uri对象
* @param context
* @param uri
* @param options
* @param maxW
* @param maxH
* @param orientation
* @param pass
* @return
*/
public static Bitmap decodeBitmap(Context context, Uri uri,
BitmapFactory.Options options, int maxW, int maxH, int orientation,
int pass) {
Bitmap bitmap = null;
Bitmap newBitmap = null;
if (pass > 10) {
return null;
}
InputStream stream = openInputStream(context, uri);
if (null == stream)
return null;
try {
bitmap = BitmapFactory.decodeStream(stream, null, options);
IOUtil.closeSilently(stream);
if (bitmap != null) {
newBitmap = BitmapUtil.resizeBitmap(bitmap, maxW, maxH,
orientation);
if (bitmap != newBitmap) {
bitmap.recycle();
}
bitmap = newBitmap;
}
} catch (OutOfMemoryError error) {
error.printStackTrace();
IOUtil.closeSilently(stream);
if (null != bitmap) {
bitmap.recycle();
bitmap = null;
}
options.inSampleSize += 1;
bitmap = decodeBitmap(context, uri, options, maxW, maxH,
orientation, pass + 1);
} catch (Exception e) {
e.printStackTrace();
}
return bitmap;
}
/**
* 重设大小
* @param input
* @param maxW
* @param maxH
* @return
*/
public static Bitmap resizeBitmap(Bitmap input, int maxW, int maxH) {
Bitmap newBitmap = null;
Bitmap bitmap = input;
if (input != null) {
try {
newBitmap = BitmapUtil.resizeBitmap(input, maxW, maxH, 0);
if (bitmap != newBitmap) {
bitmap.recycle();
}
bitmap = newBitmap;
} catch (OutOfMemoryError error) {
if (null != bitmap) {
bitmap.recycle();
bitmap = null;
}
bitmap = resizeBitmap(bitmap, maxW - 200, maxH - 200);
}
}
return bitmap;
}
/**
* 转换Uri为字符串
* @param context
* @param strUri
* @return
*/
public static String convertUri(Context context, String strUri) {
return convertUri(context, Uri.parse(strUri));
}
public static String convertUri(Context context, Uri uri) {
String scheme = uri.getScheme();
if ((scheme == null) || ("file".equals(scheme))) {
return uri.getPath();
} else {
String[] projection = { MediaStore.Images.Media.DATA };
CursorLoader loader = new CursorLoader(context, uri, projection,
null, null, null);
Cursor cursor = loader.loadInBackground();
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
}
public static InputStream openInputStream(Context context, Uri uri) {
if (null == uri)
return null;
String scheme = uri.getScheme();
InputStream stream = null;
if ((scheme == null) || ("file".equals(scheme))) {
stream = openFileInputStream(uri.getPath());
} else if ("content".equals(scheme)) {
stream = openContentInputStream(context, uri);
} else if (("http".equals(scheme)) || ("https".equals(scheme))) {
stream = openRemoteInputStream(uri);
}
return stream;
}
public static boolean decodeImageBounds(InputStream stream, int[] outSize,
BitmapFactory.Options options) {
BitmapFactory.decodeStream(stream, null, options);
if ((options.outHeight > 0) && (options.outWidth > 0)) {
outSize[0] = options.outWidth;
outSize[1] = options.outHeight;
return true;
}
return false;
}
private static int computeSampleSize(int bitmapW, int bitmapH, int maxW,
int maxH, int orientation) {
double h = 0.0;
double w = 0.0;
if ((orientation == 0) || (orientation == 180)) {
w = bitmapW;
h = bitmapH;
} else {
w = bitmapH;
h = bitmapW;
}
Log.v("dsd", "computeSampleSize w:" + w);
Log.v("dsd", "computeSampleSize h:" + h);
Log.v("dsd", "computeSampleSize bitmapW:" + bitmapW);
Log.v("dsd", "computeSampleSize bitmapH:" + bitmapH);
Log.v("dsd", "computeSampleSize w / maxW:" + w / maxW);
Log.v("dsd", "computeSampleSize h / maxH:" + h / maxH);
int sampleSize = (int) Math.ceil(Math.max(w / maxW, h / maxH));
Log.v("dsd", "computeSampleSize sampleSize:" + sampleSize);
return sampleSize;
}
/**
* 将路径转换为输入流
* @param path
* @return
*/
static InputStream openFileInputStream(String path) {
try {
return new FileInputStream(path);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return null;
}
static InputStream openContentInputStream(Context context, Uri uri) {
try {
return context.getContentResolver().openInputStream(uri);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return null;
}
static InputStream openRemoteInputStream(Uri uri) {
URL finalUrl;
try {
finalUrl = new URL(uri.toString());
} catch (MalformedURLException e) {
e.printStackTrace();
return null;
}
HttpURLConnection connection;
try {
connection = (HttpURLConnection) finalUrl.openConnection();
} catch (IOException e) {
e.printStackTrace();
return null;
}
connection.setInstanceFollowRedirects(false);
int code;
try {
code = connection.getResponseCode();
} catch (IOException e) {
e.printStackTrace();
return null;
}
if ((code == 301) || (code == 302) || (code == 303)) {
String newLocation = connection.getHeaderField("Location");
return openRemoteInputStream(Uri.parse(newLocation));
}
try {
return (InputStream) finalUrl.getContent();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public static BitmapFactory.Options getDefaultOptions() {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inScaled = false;
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
options.inDither = false;
options.inJustDecodeBounds = false;
options.inPurgeable = true;
options.inInputShareable = true;
options.inTempStorage = new byte[16384];
return options;
}
/**
* 取得图片的转向角度
* @param imageUri
* @param mimeType
* @return
*/
public static int getExifOrientation(Uri imageUri, String mimeType) {
int rotation = 0;
if ("image/jpeg".equalsIgnoreCase(mimeType)
&& "file".equals(imageUri.getScheme())) {
try {
ExifInterface exif = new ExifInterface(imageUri.getPath());
// 取得图片的旋转角度
int exifOrientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
/**
* 判断旋转角度
*/
switch (exifOrientation) {
case ExifInterface.ORIENTATION_FLIP_HORIZONTAL:
case ExifInterface.ORIENTATION_NORMAL:
rotation = 0;
break;
case ExifInterface.ORIENTATION_TRANSVERSE:
case ExifInterface.ORIENTATION_ROTATE_90:
rotation = 90;
break;
case ExifInterface.ORIENTATION_FLIP_VERTICAL:
case ExifInterface.ORIENTATION_ROTATE_180:
rotation = 180;
break;
case ExifInterface.ORIENTATION_TRANSPOSE:
case ExifInterface.ORIENTATION_ROTATE_270:
rotation = 270;
break;
}
} catch (IOException e) {
Log.e("dsd", "Can't read EXIF tags from file [%s]" + imageUri);
}
}
return rotation;
}
}