Java tutorial
//package com.java2s; //License from project: Open Source License import android.content.ContentProviderClient; import android.content.ContentResolver; import android.content.Context; import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.BitmapFactory; import android.graphics.Matrix; import android.media.ExifInterface; import android.net.Uri; import android.os.ParcelFileDescriptor; import android.provider.MediaStore; import android.util.Base64; import java.io.Closeable; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; public class Main { public static Bitmap bitmapResult = null; public static Bitmap decodeBase64(String input) { byte[] decodedByte = Base64.decode(input, 0); return bitmapResult = BitmapFactory.decodeByteArray(decodedByte, 0, decodedByte.length); } public static Bitmap decode(Context context, Uri uri, int maxW, int maxH) { InputStream stream = openInputStream(context, uri); if (null == stream) { return null; } int orientation = getExifOrientation(context, uri); Bitmap bitmap = null; int[] imageSize = new int[2]; final boolean decoded = decodeImageBounds(stream, imageSize); closeSilently(stream); if (decoded) { int sampleSize = computeSampleSize(imageSize[0], imageSize[1], (int) (maxW * 1.2), (int) (maxH * 1.2), orientation); BitmapFactory.Options options = getDefaultOptions(); options.inSampleSize = sampleSize; bitmap = decodeBitmap(context, uri, options, maxW, maxH, orientation, 0); } return bitmap; } /** * Return an {@link InputStream} from the given uri. ( can be a local * content, a file path or an http url ) * * @param context * @param uri * @return the {@link InputStream} from the given uri, null if uri cannot be * opened */ public static InputStream openInputStream(Context context, Uri uri) { if (null == uri) return null; final String scheme = uri.getScheme(); InputStream stream = null; if (scheme == null || ContentResolver.SCHEME_FILE.equals(scheme)) { // from file stream = openFileInputStream(uri.getPath()); } else if (ContentResolver.SCHEME_CONTENT.equals(scheme)) { // from content stream = openContentInputStream(context, uri); } return stream; } /** * Return the rotation of the passed image file * * @param filepath * image absolute file path * @return image orientation */ public static int getExifOrientation(final String filepath) { if (null == filepath) return 0; ExifInterface exif = null; try { exif = new ExifInterface(filepath); } catch (IOException e) { return 0; } return getExifOrientation(exif); } public static int getExifOrientation(final ExifInterface exif) { int degree = 0; if (exif != null) { final int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, -1); if (orientation != -1) { 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; } } } return degree; } /** * Return the string representation of the given orientation * * @param orientation * @return */ public static String getExifOrientation(int orientation) { switch (orientation) { case 0: return String.valueOf(ExifInterface.ORIENTATION_NORMAL); case 90: return String.valueOf(ExifInterface.ORIENTATION_ROTATE_90); case 180: return String.valueOf(ExifInterface.ORIENTATION_ROTATE_180); case 270: return String.valueOf(ExifInterface.ORIENTATION_ROTATE_270); default: throw new AssertionError("invalid: " + orientation); } } /** * Try to get the exif orientation of the passed image uri * * @param context * @param uri * @return */ public static int getExifOrientation(Context context, Uri uri) { final String scheme = uri.getScheme(); ContentProviderClient provider = null; if (scheme == null || ContentResolver.SCHEME_FILE.equals(scheme)) { return getExifOrientation(uri.getPath()); } else if (scheme.equals(ContentResolver.SCHEME_CONTENT)) { try { provider = context.getContentResolver().acquireContentProviderClient(uri); } catch (SecurityException e) { return 0; } if (provider != null) { Cursor result; try { result = provider.query(uri, new String[] { MediaStore.Images.ImageColumns.ORIENTATION, MediaStore.Images.ImageColumns.DATA }, null, null, null); } catch (Exception e) { e.printStackTrace(); return 0; } if (result == null) { return 0; } int orientationColumnIndex = result.getColumnIndex(MediaStore.Images.ImageColumns.ORIENTATION); int dataColumnIndex = result.getColumnIndex(MediaStore.Images.ImageColumns.DATA); try { if (result.getCount() > 0) { result.moveToFirst(); int rotation = 0; if (orientationColumnIndex > -1) { rotation = result.getInt(orientationColumnIndex); } if (dataColumnIndex > -1) { String path = result.getString(dataColumnIndex); rotation |= getExifOrientation(path); } return rotation; } } finally { result.close(); } } } return 0; } public static boolean decodeImageBounds(final InputStream stream, int[] outSize) { BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeStream(stream, null, options); if (options.outHeight > 0 && options.outWidth > 0) { outSize[0] = options.outWidth; outSize[1] = options.outHeight; return true; } return false; } public static void closeSilently(final Closeable c) { if (c == null) return; try { c.close(); } catch (final Throwable t) { } } public static void closeSilently(final ParcelFileDescriptor c) { if (c == null) return; try { c.close(); } catch (final Throwable t) { } } public static void closeSilently(Cursor cursor) { if (cursor == null) return; try { if (cursor != null) cursor.close(); } catch (Throwable t) { } } private static int computeSampleSize(final int bitmapW, final int bitmapH, final int maxW, final int maxH, final int orientation) { double w, h; if (orientation == 0 || orientation == 180) { w = bitmapW; h = bitmapH; } else { w = bitmapH; h = bitmapW; } final int sampleSize = (int) Math.ceil(Math.max(w / maxW, h / maxH)); return sampleSize; } static BitmapFactory.Options getDefaultOptions() { BitmapFactory.Options options = new BitmapFactory.Options(); options.inScaled = false; options.inPreferredConfig = Config.ARGB_8888; options.inDither = false; options.inJustDecodeBounds = false; options.inPurgeable = true; options.inInputShareable = true; options.inTempStorage = new byte[16 * 1024]; return options; } 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 > 20) { return null; } InputStream stream = openInputStream(context, uri); if (null == stream) return null; try { // decode the bitmap via android BitmapFactory bitmap = BitmapFactory.decodeStream(stream, null, options); closeSilently(stream); if (bitmap != null) { newBitmap = resizeBitmap(bitmap, maxW, maxH, orientation); if (bitmap != newBitmap) { bitmap.recycle(); } bitmap = newBitmap; } } catch (OutOfMemoryError error) { closeSilently(stream); if (null != bitmap) { bitmap.recycle(); } options.inSampleSize += 1; bitmap = decodeBitmap(context, uri, options, maxW, maxH, orientation, pass + 1); } return bitmap; } /** * Return a {@link FileInputStream} from the given path or null if file not * found * * @param path * the file path * @return the {@link FileInputStream} of the given path, null if * {@link FileNotFoundException} is thrown */ static InputStream openFileInputStream(String path) { try { return new FileInputStream(path); } catch (FileNotFoundException e) { e.printStackTrace(); } return null; } /** * Return a {@link BufferedInputStream} from the given uri or null if an * exception is thrown * * @param context * @param uri * @return the {@link InputStream} of the given path. null if file is not * found */ static InputStream openContentInputStream(Context context, Uri uri) { try { return context.getContentResolver().openInputStream(uri); } catch (FileNotFoundException e) { e.printStackTrace(); } return null; } public static Bitmap resizeBitmap(final Bitmap input, int destWidth, int destHeight) throws OutOfMemoryError { return resizeBitmap(input, destWidth, destHeight, 0); } /** * Resize a bitmap object to fit the passed width and height * * @param input * The bitmap to be resized * @param destWidth * Desired maximum width of the result bitmap * @param destHeight * Desired maximum height of the result bitmap * @return A new resized bitmap * @throws OutOfMemoryError * if the operation exceeds the available vm memory */ public static Bitmap resizeBitmap(final Bitmap input, int destWidth, int destHeight, int rotation) throws OutOfMemoryError { int dstWidth = destWidth; int dstHeight = destHeight; final int srcWidth = input.getWidth(); final int srcHeight = input.getHeight(); if (rotation == 90 || rotation == 270) { dstWidth = destHeight; dstHeight = destWidth; } boolean needsResize = false; float p; if ((srcWidth > dstWidth) || (srcHeight > dstHeight)) { needsResize = true; if ((srcWidth > srcHeight) && (srcWidth > dstWidth)) { p = (float) dstWidth / (float) srcWidth; dstHeight = (int) (srcHeight * p); } else { p = (float) dstHeight / (float) srcHeight; dstWidth = (int) (srcWidth * p); } } else { dstWidth = srcWidth; dstHeight = srcHeight; } if (needsResize || rotation != 0) { Bitmap output; if (rotation == 0) { output = Bitmap.createScaledBitmap(input, dstWidth, dstHeight, true); } else { Matrix matrix = new Matrix(); matrix.postScale((float) dstWidth / srcWidth, (float) dstHeight / srcHeight); matrix.postRotate(rotation); output = Bitmap.createBitmap(input, 0, 0, srcWidth, srcHeight, matrix, true); } return output; } else return input; } }