• Android ImageResizer:inSampleSize


    import android.annotation.TargetApi;
    import android.content.Context;
    import android.content.res.Resources;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.os.Build;
    
    import com.example.android.common.logger.Log;
    import com.example.android.displayingbitmaps.BuildConfig;
    
    import java.io.FileDescriptor;
    
    /**
     * A simple subclass of {@link ImageWorker} that resizes images from resources given a target width
     * and height. Useful for when the input images might be too large to simply load directly into
     * memory.
     */
    public class ImageResizer extends ImageWorker {
        private static final String TAG = "ImageResizer";
        protected int mImageWidth;
        protected int mImageHeight;
    
        /**
         * Initialize providing a single target image size (used for both width and height);
         *
         * @param context
         * @param imageWidth
         * @param imageHeight
         */
        public ImageResizer(Context context, int imageWidth, int imageHeight) {
            super(context);
            setImageSize(imageWidth, imageHeight);
        }
    
        /**
         * Initialize providing a single target image size (used for both width and height);
         *
         * @param context
         * @param imageSize
         */
        public ImageResizer(Context context, int imageSize) {
            super(context);
            setImageSize(imageSize);
        }
    
        /**
         * Set the target image width and height.
         *
         * @param width
         * @param height
         */
        public void setImageSize(int width, int height) {
            mImageWidth = width;
            mImageHeight = height;
        }
    
        /**
         * Set the target image size (width and height will be the same).
         *
         * @param size
         */
        public void setImageSize(int size) {
            setImageSize(size, size);
        }
    
        /**
         * The main processing method. This happens in a background task. In this case we are just
         * sampling down the bitmap and returning it from a resource.
         *
         * @param resId
         * @return
         */
        private Bitmap processBitmap(int resId) {
            if (BuildConfig.DEBUG) {
                Log.d(TAG, "processBitmap - " + resId);
            }
            return decodeSampledBitmapFromResource(mResources, resId, mImageWidth,
                    mImageHeight, getImageCache());
        }
    
        @Override
        protected Bitmap processBitmap(Object data) {
            return processBitmap(Integer.parseInt(String.valueOf(data)));
        }
    
        /**
         * Decode and sample down a bitmap from resources to the requested width and height.
         *
         * @param res The resources object containing the image data
         * @param resId The resource id of the image data
         * @param reqWidth The requested width of the resulting bitmap
         * @param reqHeight The requested height of the resulting bitmap
         * @param cache The ImageCache used to find candidate bitmaps for use with inBitmap
         * @return A bitmap sampled down from the original with the same aspect ratio and dimensions
         *         that are equal to or greater than the requested width and height
         */
        public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
                int reqWidth, int reqHeight, ImageCache cache) {
    
            // BEGIN_INCLUDE (read_bitmap_dimensions)
            // First decode with inJustDecodeBounds=true to check dimensions
            final BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;
            BitmapFactory.decodeResource(res, resId, options);
    
            // Calculate inSampleSize
            options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
            // END_INCLUDE (read_bitmap_dimensions)
    
            // If we're running on Honeycomb or newer, try to use inBitmap
            if (Utils.hasHoneycomb()) {
                addInBitmapOptions(options, cache);
            }
    
            // Decode bitmap with inSampleSize set
            options.inJustDecodeBounds = false;
            return BitmapFactory.decodeResource(res, resId, options);
        }
    
        /**
         * Decode and sample down a bitmap from a file to the requested width and height.
         *
         * @param filename The full path of the file to decode
         * @param reqWidth The requested width of the resulting bitmap
         * @param reqHeight The requested height of the resulting bitmap
         * @param cache The ImageCache used to find candidate bitmaps for use with inBitmap
         * @return A bitmap sampled down from the original with the same aspect ratio and dimensions
         *         that are equal to or greater than the requested width and height
         */
        public static Bitmap decodeSampledBitmapFromFile(String filename,
                int reqWidth, int reqHeight, ImageCache cache) {
    
            // First decode with inJustDecodeBounds=true to check dimensions
            final BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;
            BitmapFactory.decodeFile(filename, options);
    
            // Calculate inSampleSize
            options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
    
            // If we're running on Honeycomb or newer, try to use inBitmap
            if (Utils.hasHoneycomb()) {
                addInBitmapOptions(options, cache);
            }
    
            // Decode bitmap with inSampleSize set
            options.inJustDecodeBounds = false;
            return BitmapFactory.decodeFile(filename, options);
        }
    
        /**
         * Decode and sample down a bitmap from a file input stream to the requested width and height.
         *
         * @param fileDescriptor The file descriptor to read from
         * @param reqWidth The requested width of the resulting bitmap
         * @param reqHeight The requested height of the resulting bitmap
         * @param cache The ImageCache used to find candidate bitmaps for use with inBitmap
         * @return A bitmap sampled down from the original with the same aspect ratio and dimensions
         *         that are equal to or greater than the requested width and height
         */
        public static Bitmap decodeSampledBitmapFromDescriptor(
                FileDescriptor fileDescriptor, int reqWidth, int reqHeight, ImageCache cache) {
    
            // First decode with inJustDecodeBounds=true to check dimensions
            final BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;
            BitmapFactory.decodeFileDescriptor(fileDescriptor, null, options);
    
            // Calculate inSampleSize
            options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
    
            // Decode bitmap with inSampleSize set
            options.inJustDecodeBounds = false;
    
            // If we're running on Honeycomb or newer, try to use inBitmap
            if (Utils.hasHoneycomb()) {
                addInBitmapOptions(options, cache);
            }
    
            return BitmapFactory.decodeFileDescriptor(fileDescriptor, null, options);
        }
    
        @TargetApi(Build.VERSION_CODES.HONEYCOMB)
        private static void addInBitmapOptions(BitmapFactory.Options options, ImageCache cache) {
    
            // inBitmap only works with mutable bitmaps so force the decoder to
            // return mutable bitmaps.
            options.inMutable = true;
    
            if (cache != null) {
                // Try and find a bitmap to use for inBitmap
                Bitmap inBitmap = cache.getBitmapFromReusableSet(options);
    
                if (inBitmap != null) {
                    options.inBitmap = inBitmap;
                }
            }
    
        }
    
        /**
         * Calculate an inSampleSize for use in a {@link android.graphics.BitmapFactory.Options} object when decoding
         * bitmaps using the decode* methods from {@link android.graphics.BitmapFactory}. This implementation calculates
         * the closest inSampleSize that is a power of 2 and will result in the final decoded bitmap
         * having a width and height equal to or larger than the requested width and height.
         *
         * @param options An options object with out* params already populated (run through a decode*
         *            method with inJustDecodeBounds==true
         * @param reqWidth The requested width of the resulting bitmap
         * @param reqHeight The requested height of the resulting bitmap
         * @return The value to be used for inSampleSize
         */
        public static int calculateInSampleSize(BitmapFactory.Options options,
                int reqWidth, int reqHeight) {
            // BEGIN_INCLUDE (calculate_sample_size)
            // Raw height and width of image
            final int height = options.outHeight;
            final int width = options.outWidth;
            int inSampleSize = 1;
    
            if (height > reqHeight || width > reqWidth) {
    
                final int halfHeight = height / 2;
                final int halfWidth = width / 2;
    
                // Calculate the largest inSampleSize value that is a power of 2 and keeps both
                // height and width larger than the requested height and width.
                while ((halfHeight / inSampleSize) > reqHeight
                        && (halfWidth / inSampleSize) > reqWidth) {
                    inSampleSize *= 2;
                }
    
                // This offers some additional logic in case the image has a strange
                // aspect ratio. For example, a panorama may have a much larger
                // width than height. In these cases the total pixels might still
                // end up being too large to fit comfortably in memory, so we should
                // be more aggressive with sample down the image (=larger inSampleSize).
    
                long totalPixels = width * height / inSampleSize;
    
                // Anything more than 2x the requested pixels we'll sample down further
                final long totalReqPixelsCap = reqWidth * reqHeight * 2;
    
                while (totalPixels > totalReqPixelsCap) {
                    inSampleSize *= 2;
                    totalPixels /= 2;
                }
            }
            return inSampleSize;
            // END_INCLUDE (calculate_sample_size)
        }
    }

    DisplayingBitmaps.rar

  • 相关阅读:
    Linux 进程间通信(一)(经典IPC:消息队列、信号量、共享存储)
    Linux 进程间通信(一)(经典IPC:管道、FIFO)
    Linux I/O 进阶
    Linux 信号
    Linux 进程(二):进程关系及其守护进程
    转载:什么是B+树?
    转载:什么是B树?
    Redis批量删除脚本
    Java时间工具类
    JSP2.2自定义标签、EL函数
  • 原文地址:https://www.cnblogs.com/onelikeone/p/7586861.html
Copyright © 2020-2023  润新知