Advertisement
ulfben

BitmapUtils (Android)

Jan 25th, 2018
437
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 4.97 KB | None | 0 0
  1. import android.content.Context;
  2. import android.content.res.Resources;
  3. import android.graphics.Bitmap;
  4. import android.graphics.BitmapFactory;
  5. import android.graphics.Point;
  6.  
  7. public class BitmapUtils {
  8.     private static final String TAG = "BitmapUtils";
  9.     private static final boolean FILTER = true;
  10.     private static BitmapFactory.Options _options = new BitmapFactory.Options(); //Q&D pool, assumes single threading
  11.     private static Point _dimensions = new Point(0,0); //Q&D  pool, assumes single threading
  12.  
  13.     private BitmapUtils(){super();}
  14.  
  15.     //Set either of the dimensions for aspect-correct scaling, or both to force the aspect.
  16.     public static Bitmap loadScaledBitmap(final Context context, final String bitmapName,
  17.                                           final int targetWidth, final int targetHeight) throws OutOfMemoryError {
  18.         final Resources res = context.getResources();
  19.         final int resID = res.getIdentifier(bitmapName, "drawable", context.getPackageName());
  20.         return loadScaledBitmap(res, resID, targetWidth, targetHeight);
  21.     }
  22.  
  23.     //Set either of the dimensions for aspect-correct scaling, or both to force the aspect.
  24.     public static Bitmap loadScaledBitmap(final Resources res, final int resID,
  25.                                           final int targetWidth, final int targetHeight) throws OutOfMemoryError{
  26.         _options = readBitmapMetaData(res, resID); //parse raw file info into _options
  27.         _dimensions = scaleToTargetDimensions(targetWidth, targetHeight, _options.outWidth, _options.outHeight);
  28.         Bitmap bitmap = loadSubSampledBitmap(res, resID, _dimensions.x, _dimensions.y, _options);
  29.         if(bitmap != null){
  30.             if(bitmap.getHeight() != _dimensions.y || bitmap.getWidth() != _dimensions.x) {
  31.                 //scale to pixel-perfect dimensions in case we have non-uniform density on x / y
  32.                 bitmap = Bitmap.createScaledBitmap(bitmap, _dimensions.x, _dimensions.y, FILTER);
  33.             }
  34.         }
  35.         return bitmap;
  36.     }
  37.  
  38.     private static Bitmap loadSubSampledBitmap(final Resources res, final int resId, final int targetWidth, final int targetHeight, final BitmapFactory.Options opts) {
  39.         opts.inSampleSize = calculateInSampleSize(opts, targetWidth, targetHeight); //calculates clostest POT sample factor
  40.         opts.inJustDecodeBounds = false;
  41.         opts.inScaled = true; //scale after subsampling, to reach exact target density.
  42.         if(targetHeight > 0) {
  43.             opts.inDensity = opts.outHeight;
  44.             opts.inTargetDensity = targetHeight * opts.inSampleSize;
  45.         }else {
  46.             opts.inDensity = opts.outWidth;
  47.             opts.inTargetDensity = targetWidth * opts.inSampleSize;
  48.         }
  49.         return BitmapFactory.decodeResource(res, resId, opts);
  50.     }
  51.  
  52.     private static int calculateInSampleSize(final BitmapFactory.Options opts, final int reqWidth, final int reqHeight) {
  53.         final int height = opts.outHeight;// original height and width of image
  54.         final int width = opts.outWidth;
  55.         int inSampleSize = 1;
  56.         if(height > reqHeight || width > reqWidth) {
  57.             final int halfHeight = height / 2;
  58.             final int halfWidth = width / 2;
  59.             // Calculate the largest inSampleSize value that is a power of 2 and keeps both
  60.             // height and width larger than the requested height and width.
  61.             while ((halfHeight / inSampleSize) >= reqHeight && (halfWidth / inSampleSize) >= reqWidth) {
  62.                 inSampleSize *= 2;
  63.             }
  64.         }
  65.         return inSampleSize;
  66.     }
  67.  
  68.     //loads metadata about a Bitmap into the Options object. Does *not* load the Bitmap.
  69.     private static BitmapFactory.Options readBitmapMetaData(final Resources res, final int resID){
  70.         _options.inJustDecodeBounds = true;
  71.         BitmapFactory.decodeResource(res, resID, _options);
  72.         _options.inJustDecodeBounds = false;
  73.         return _options;
  74.     }
  75.  
  76.     //provide both or either of targetWidth / targetHeight. If one is left at 0, the other is calculated
  77.     //based on source-dimensions. Ergo; should scale and keep aspect ratio.
  78.     private static Point scaleToTargetDimensions(float targetWidth, float targetHeight,
  79.                                                  final float srcWidth, final float srcHeight){
  80.         if (targetWidth <= 0 && targetHeight <= 0){
  81.             targetWidth = srcWidth;
  82.             targetHeight = srcHeight;
  83.         }
  84.         _dimensions.x = (int) targetWidth;
  85.         _dimensions.y = (int) targetHeight;
  86.         if(targetWidth == 0 || targetHeight == 0){
  87.             //formula: new height = (original height / original width) x new width
  88.             if(targetHeight > 0) { //if Y is configured, calculate X
  89.                 _dimensions.x = (int) ((srcWidth / srcHeight) * targetHeight);
  90.             }else { //calculate Y
  91.                 _dimensions.y = (int) ((srcHeight / srcWidth) * targetWidth);
  92.             }
  93.         }
  94.         return _dimensions;
  95.     }
  96. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement