Java tutorial
//package com.java2s; //License from project: Apache License import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Matrix; import android.media.ExifInterface; import java.io.IOException; public class Main { /** * author: liuxu * decode bitmap with minimum memory. * NOTE: if image quality is your first concern, do not use this method. * @param path full path for the picture * @return bitmap */ public static Bitmap file2bitmap(String path) { return file2bitmap(path, 0, 0, true); } public static Bitmap file2bitmap(String path, int width, int height) { return file2bitmap(path, width, height, true); } /** * author: liuxu * de-sample according to given width and height. if required width or height is * smaller than the origin picture's with or height, de-sample it. * NOTE: if image quality is your first concern, do not use this method. * @param path full path for the picture * @param width the required width * @param height the required height * @param considerExifRotate true and the bitmap will be rotated according to exif (if exists) * @return bitmap */ public static Bitmap file2bitmap(String path, int width, int height, boolean considerExifRotate) { final BitmapFactory.Options options = new BitmapFactory.Options(); if (width != 0 && height != 0) { // decode with inJustDecodeBounds=true to check size options.inJustDecodeBounds = true; BitmapFactory.decodeFile(path, options); // calculate inSampleSize according to the requested size options.inSampleSize = calculateInSampleSize(options, width, height); options.inJustDecodeBounds = false; } // decode bitmap with the calculated inSampleSize options.inPreferredConfig = Bitmap.Config.RGB_565; options.inPurgeable = true; options.inInputShareable = true; Bitmap bitmap = BitmapFactory.decodeFile(path, options); if (considerExifRotate) { int exifDegree = getFileExifDegree(path); if (exifDegree == 0) { return bitmap; } else { return rotateBitmap(bitmap, exifDegree); } } else { return bitmap; } } /** * author: liuxu * de-sample according to given width and height * @param options options * @param reqWidth the required width * @param reqHeight the required height * @return the calculated sample size */ private static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { // raw height and width of image final int height = options.outHeight; final int width = options.outWidth; int initSize = 1; if (height > reqHeight || width > reqWidth) { if (width < height) { initSize = Math.round((float) height / (float) reqHeight); } else { initSize = Math.round((float) width / (float) reqWidth); } } /* * 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 * down samples an image by 2 even though the request is 3. */ int roundedSize; if (initSize <= 8) { roundedSize = 1; while (roundedSize < initSize) { roundedSize <<= 1; } } else { roundedSize = (initSize + 7) / 8 * 8; } return roundedSize; } public static int getFileExifDegree(String path) { try { ExifInterface exifInterface = new ExifInterface(path); int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); switch (orientation) { case ExifInterface.ORIENTATION_ROTATE_90: return 90; case ExifInterface.ORIENTATION_ROTATE_180: return 180; case ExifInterface.ORIENTATION_ROTATE_270: return 270; } } catch (IOException e) { e.printStackTrace(); } return 0; } public static Bitmap rotateBitmap(Bitmap src, int degree) { Bitmap ret = null; Matrix matrix = new Matrix(); matrix.postRotate(degree); try { ret = Bitmap.createBitmap(src, 0, 0, src.getWidth(), src.getHeight(), matrix, true); } catch (OutOfMemoryError ignore) { } if (ret == null) { ret = src; } if (src != ret) { src.recycle(); } return ret; } }