Home | History | Annotate | Download | only in common
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 package com.android.car.apps.common;
     17 
     18 import android.graphics.Bitmap;
     19 import android.util.Log;
     20 
     21 public class BitmapUtils {
     22     private static final String TAG = "BitmapUtils";
     23 
     24     /**
     25      * Scales a bitmap while preserving the proportions such that both dimensions are the smallest
     26      * values possible that are equal to or larger than the given dimensions.
     27      *
     28      * This function can be a few times as expensive as Bitmap.createScaledBitmap with
     29      * filtering when downscaling, but it produces much nicer results.
     30      *
     31      * @param bm The bitmap to scale.
     32      * @param width The desired width.
     33      * @param height The desired height.
     34      * @return The scaled bitmap, or the original bitmap if scaling was not necessary.
     35      */
     36     public static Bitmap scaleBitmap(Bitmap bm, int width, int height) {
     37         if (bm == null || (bm.getHeight() == height && bm.getWidth() == width)) {
     38             return bm;
     39         }
     40 
     41         float heightScale = 1f;
     42         if (bm.getHeight() > height) {
     43             heightScale = (float) height / bm.getHeight();
     44         }
     45         float widthScale = 1f;
     46         if (bm.getWidth() > width) {
     47             widthScale = (float) width / bm.getWidth();
     48         }
     49         float scale = heightScale > widthScale ? heightScale : widthScale;
     50         int scaleWidth = (int) Math.ceil(bm.getWidth() * scale);
     51         int scaleHeight = (int) Math.ceil(bm.getHeight() * scale);
     52 
     53         Bitmap scaledBm = bm;
     54         // If you try to scale an image down too much in one go, you can end up with discontinuous
     55         // interpolation. Therefore, if necessary, we scale the image to twice the desired size
     56         // and do a second scaling to the desired size, which smooths jaggedness from the first go.
     57         if (scale < .5f) {
     58             scaledBm = Bitmap.createScaledBitmap(scaledBm, scaleWidth * 2, scaleHeight * 2, true);
     59         }
     60 
     61         if (scale != 1f) {
     62             Bitmap newScaledBitmap = Bitmap
     63                     .createScaledBitmap(scaledBm, scaleWidth, scaleHeight, true);
     64             if (scaledBm != bm) {
     65                 scaledBm.recycle();
     66             }
     67             scaledBm = newScaledBitmap;
     68         }
     69         return scaledBm;
     70     }
     71 
     72     /**
     73      * Crops the given bitmap to a centered rectangle of the given dimensions.
     74      *
     75      * @param bm the bitmap to crop.
     76      * @param width the width to crop to.
     77      * @param height the height to crop to.
     78      * @return The cropped bitmap, or the original if no cropping was necessary.
     79      */
     80     public static Bitmap cropBitmap(Bitmap bm, int width, int height) {
     81         if (bm == null) {
     82             return bm;
     83         }
     84         if (bm.getHeight() < height || bm.getWidth() < width) {
     85             if (Log.isLoggable(TAG, Log.INFO)) {
     86                 Log.i(TAG, String.format(
     87                         "Can't crop bitmap to larger dimensions (%d, %d) -> (%d, %d).",
     88                         bm.getWidth(), bm.getHeight(), width, height));
     89             }
     90             return bm;
     91         }
     92         int x = (bm.getWidth() - width) / 2;
     93         int y =(bm.getHeight() - height) / 2;
     94         return Bitmap.createBitmap(bm, x, y, width, height);
     95     }
     96 }
     97