Rotate, transform Bitmap : Bitmap « 2D Graphics « Android






Rotate, transform Bitmap

    
/*
 *    Copyright (C) 2010 Stewart Gateley <birbeck@gmail.com>
 *
 *    This program is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

//package com.birbeck.wallpaperslideshow;

import java.io.File;
import java.io.FileFilter;
import java.util.Collection;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.util.Log;

/**
 * Collection of utility functions used in this package.
 */
public class BitmapUtil {
  public static final int UNCONSTRAINED = -1;
    private static final String TAG = "BitmapUtil";

    public BitmapUtil() {
    }

    // Rotates the bitmap by the specified degree.
    // If a new bitmap is created, the original bitmap is recycled.
    public static Bitmap rotate(Bitmap b, int degrees, Matrix m) {
        if (degrees != 0 && b != null) {
          if (m == null) {
            m = new Matrix();
          }
            m.setRotate(degrees,
                    (float) b.getWidth() / 2, (float) b.getHeight() / 2);
            try {
                Bitmap b2 = Bitmap.createBitmap(
                        b, 0, 0, b.getWidth(), b.getHeight(), m, true);
                if (b != b2) {
                    b.recycle();
                    b = b2;
                }
            } catch (OutOfMemoryError ex) {
                // We have no memory to rotate. Return the original bitmap.
                Log.e(TAG, "Got oom exception ", ex);
            }
        }
        return b;
    }

    /*
     * Compute the sample size as a function of minSideLength
     * and maxNumOfPixels.
     * minSideLength is used to specify that minimal width or height of a
     * bitmap.
     * maxNumOfPixels is used to specify the maximal size in pixels that is
     * tolerable in terms of memory usage.
     *
     * The function returns a sample size based on the constraints.
     * Both size and minSideLength can be passed in as IImage.UNCONSTRAINED,
     * which indicates no care of the corresponding constraint.
     * The functions prefers returning a sample size that
     * generates a smaller bitmap, unless minSideLength = IImage.UNCONSTRAINED.
     *
     * Also, 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 downsamples an image by 2 even though the
     * request is 3. So we round up the sample size to avoid OOM.
     */
    public static int computeSampleSize(BitmapFactory.Options options,
            int minSideLength, int maxNumOfPixels) {
        int initialSize = computeInitialSampleSize(options, minSideLength,
                maxNumOfPixels);

        int roundedSize;
        if (initialSize <= 8) {
            roundedSize = 1;
            while (roundedSize < initialSize) {
                roundedSize <<= 1;
            }
        } else {
            roundedSize = (initialSize + 7) / 8 * 8;
        }

        return roundedSize;
    }

    private static int computeInitialSampleSize(BitmapFactory.Options options,
            int minSideLength, int maxNumOfPixels) {
        double w = options.outWidth;
        double h = options.outHeight;

        int lowerBound = (maxNumOfPixels == UNCONSTRAINED) ? 1 :
                (int) Math.ceil(Math.sqrt(w * h / maxNumOfPixels));
        int upperBound = (minSideLength == UNCONSTRAINED) ? 128 :
                (int) Math.min(Math.floor(w / minSideLength),
                Math.floor(h / minSideLength));

        if (upperBound < lowerBound) {
            // return the larger one when there is no overlapping zone.
            return lowerBound;
        }

        if ((maxNumOfPixels == UNCONSTRAINED) &&
                (minSideLength == UNCONSTRAINED)) {
            return 1;
        } else if (minSideLength == UNCONSTRAINED) {
            return lowerBound;
        } else {
            return upperBound;
        }
    }

    public static Bitmap transform(Matrix scaler,
                                   Bitmap source,
                                   int targetWidth,
                                   int targetHeight,
                                   boolean scaleUp,
                                   boolean recycle) {
        int deltaX = source.getWidth() - targetWidth;
        int deltaY = source.getHeight() - targetHeight;
        if (!scaleUp && (deltaX < 0 || deltaY < 0)) {
            /*
             * In this case the bitmap is smaller, at least in one dimension,
             * than the target.  Transform it by placing as much of the image
             * as possible into the target and leaving the top/bottom or
             * left/right (or both) black.
             */
            Bitmap b2 = Bitmap.createBitmap(targetWidth, targetHeight,
                    Bitmap.Config.ARGB_8888);
            Canvas c = new Canvas(b2);

            int deltaXHalf = Math.max(0, deltaX / 2);
            int deltaYHalf = Math.max(0, deltaY / 2);
            Rect src = new Rect(
                    deltaXHalf,
                    deltaYHalf,
                    deltaXHalf + Math.min(targetWidth, source.getWidth()),
                    deltaYHalf + Math.min(targetHeight, source.getHeight()));
            int dstX = (targetWidth  - src.width())  / 2;
            int dstY = (targetHeight - src.height()) / 2;
            Rect dst = new Rect(
                    dstX,
                    dstY,
                    targetWidth - dstX,
                    targetHeight - dstY);
            c.drawBitmap(source, src, dst, null);
            if (recycle) {
                source.recycle();
            }
            return b2;
        }
        float bitmapWidthF = source.getWidth();
        float bitmapHeightF = source.getHeight();

        float bitmapAspect = bitmapWidthF / bitmapHeightF;
        float viewAspect   = (float) targetWidth / targetHeight;

        if (bitmapAspect > viewAspect) {
            float scale = targetHeight / bitmapHeightF;
            if (scale < .9F || scale > 1F) {
                scaler.setScale(scale, scale);
            } else {
                scaler = null;
            }
        } else {
            float scale = targetWidth / bitmapWidthF;
            if (scale < .9F || scale > 1F) {
                scaler.setScale(scale, scale);
            } else {
                scaler = null;
            }
        }

        Bitmap b1;
        if (scaler != null) {
            // this is used for minithumb and crop, so we want to filter here.
            b1 = Bitmap.createBitmap(source, 0, 0,
                    source.getWidth(), source.getHeight(), scaler, true);
        } else {
            b1 = source;
        }

        if (recycle && b1 != source) {
            source.recycle();
        }

        int dx1 = Math.max(0, b1.getWidth() - targetWidth);
        int dy1 = Math.max(0, b1.getHeight() - targetHeight);

        Bitmap b2 = Bitmap.createBitmap(
                b1,
                dx1 / 2,
                dy1 / 2,
                targetWidth,
                targetHeight);

        if (b2 != b1) {
            if (recycle || b1 != source) {
                b1.recycle();
            }
        }

        return b2;
    }

    /**
     * Make a bitmap from a given Uri.
     *
     * @param uri
     */
    public static Bitmap makeBitmap(int minSideLength, int maxNumOfPixels,
            String pathName, BitmapFactory.Options options) {
        try {
            if (options == null) options = new BitmapFactory.Options();

            options.inJustDecodeBounds = true;
            BitmapFactory.decodeFile(pathName, options);
            if (options.mCancel || options.outWidth == -1
                    || options.outHeight == -1) {
                return null;
            }
            
            options.inSampleSize = computeSampleSize(
                    options, minSideLength, maxNumOfPixels);
            options.inJustDecodeBounds = false;
            //options.inDither = false;
            //options.inPreferredConfig = Bitmap.Config.ARGB_8888;
            return BitmapFactory.decodeFile(pathName, options);
        } catch (OutOfMemoryError ex) {
            Log.e(TAG, "Got oom exception ", ex);
            return null;
        }
    }

    public static String getExtension(String name) {
        String ext = null;
        int i = name.lastIndexOf('.');

        if (i > 0 &&  i < name.length() - 1) {
            ext = name.substring(i+1).toLowerCase();
        }
        
        return ext;
    }
    
    public static File[] listFiles(File directory, boolean recurse, FileFilter filter) {
      if (!recurse) {
        return directory.listFiles(filter);
      } else {
        Collection<File> mFiles = new java.util.LinkedList<File>();
            innerListFiles(mFiles, directory, filter);
            return (File[]) mFiles.toArray(new File[mFiles.size()]);
        }
    }

    public static void innerListFiles(Collection<File> files, File directory,
            FileFilter filter) {
        File[] found = directory.listFiles();
        if (found != null) {
            for (int i = 0; i < found.length; i++) {
                if (found[i].isDirectory()) {
                    innerListFiles(files, found[i], filter);
                } else {
                  File[] found2 = directory.listFiles((FileFilter) filter);
                  for (int j = 0; j < found2.length; j++) {
                    files.add(found2[j]);
                  }
                }
            }
        }
    }
    
}

   
    
    
    
  








Related examples in the same category

1.Using BitmapFactory to decode Resource
2.Capture and save to Bitmap
3.Bitmap size
4.Draw Bitmap on Canvas
5.Bitmap.createBitmap
6.Draw Bitmap on Canvas with Matrix
7.Create a Bitmap for drawing
8.Load Bitmap and Draw
9.Bitmap and RenderScript
10.Alpha Bitmap
11.Load Bitmap from InputStream
12.Bitmap Decode
13.Bitmap Mesh
14.Bitmap Pixels
15.Create a Bitmap
16.Bitmap.Config.ARGB_8888,Bitmap.Config.RGB_565, Bitmap.Config.ARGB_4444
17.Purgeable Bitmap
18.Create a bitmap with a circle
19.This activity demonstrates various ways density can cause the scaling of bitmaps and drawables.
20.Get the current system wallpaper, modifies it and sets the modified bitmap as system wallpaper.
21.Bitmap cache by WeakHashMap
22.Memory Cache for Bitmap
23.Load Bitmap from resource
24.Crop Bitmap
25.Create Scaled Bitmap
26.downloading a bitmap image from http and setting it to given image view asynchronously
27.Get Bitmap From Local Path
28.Get Bitmap From Bytes
29.Compress Bitmap
30.Resize Bitmap
31.captures given view and converts it to a bitmap
32.Save Bitmap and BitmapFactory.decodeFile
33.Generate a blurred bitmap from given one
34.Get Bitmap From Name
35.Load Bitmap with Context
36.Load Bitmap from InputStream
37.Get Bitmap from Url with HttpURLConnection
38.Rotate Bitmap
39.Get Texture From Bitmap Resource and BitmapFactory.decodeStream
40.Drawable to Bitmap
41.Save Bitmap to and load from External Storage
42.Get Image Bitmap From Url
43.Scale Bitmap
44.Unscaled Bitmap Loader
45.Save Bitmap to External Storage Directory
46.Compress and save Bitmap image
47.Bitmap downloading, processing
48.Rotate a Bitmap
49.Save/load Bitmap
50.Find components of color of the bitmap at x, y.
51.get Bitmap From Url
52.Draw Bitmap and Drawable
53.Rotate specified Bitmap by a random angle. Scales the specified Bitmap to fit within the specified dimensions.
54.Loads a bitmap from the specified url.
55.Bitmap Refelection
56.Create a transparent bitmap from an existing bitmap by replacing certain color with transparent
57.Get Texture From Bitmap Resource
58.Bitmap Resize
59.bitmap to Byte
60.Flip Image
61.Scale an Image
62.Translate Image
63.Image Mirror
64.Moving an Image with Motion
65.Draw on Picture and save
66.Calculate optimal preview size from given parameters
67.generate Mipmaps For Bound Texture
68.Provides common tools for manipulating Bitmap objects.