Imageloader<8>-压缩图片

通过采样率压缩图片的步骤:

  1. 将BitmapFactory.Options的inJustDecodeBounds参数设置为true并加载图片
  2. 从BitmapFactory.Options中取出图片的原始宽和高 ,分别对应outWidth和outHeight
  3. 根据采样率的就着并结合目标View的所需大小计算出采样率inSampleSize
  4. 将BitmapFactory.Options的inJustDecodeBounds参数设置为false,然后重新加载图片

BTW: 说一下BitmapFactory.Options的inJustDecodeBounds属性,当参数设置为true时,BitmapFactory只会解析图片的原始宽和高,并不会将图片加载到内存中。


 // 如果图片不存在 则添加到任务队列中
            addTask(new Runnable() {
                @Override
                public void run() {
                    // 加载图片 TODO
                    // 1.获取图片需要显示的宽和搞
                    ImageSize imageSize = getImageViewSize(imageView);
                    // 利用Options压缩图片
                    Bitmap bm = decodeSampledBitmapFromPath(path, imageSize.width, imageSize.height);
                    // 添加到LruCache中
                    addBitmapToLruCache(path, bm);
                    // 发送消息,通知UIHandler更新图片
                    ImageBeanHoler holder = new ImageBeanHoler();
                    holder.bitmap = getBitmapFromLruCache(path);
                    holder.imageView = imageView;
                    holder.path = path;
                    Message message = Message.obtain();
                    message.obj = holder;
                    mUIHandler.sendMessage(message);
                    // 执行完之后,释放一个信号量,通知mPoolThread可以从任务队列中获取下一个任务了去执行了。
                    mPoolThreadSemaphore.release();
                }
            });
/**
     * 根据计算的inSampleSize得到压缩的图片
     *
     * @param path
     * @param reqWidth
     * @param reqHeight
     * @return
     */
    private Bitmap decodeSampledBitmapFromPath(String path, int reqWidth, int reqHeight) {
        // 第一次解析将inJustDecodeBounds设置为true,不将图片加载到内存,获取图片的大小
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(path, options);
        // 计算inSampleSize
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

        // 使用获取到的inSampleSize再此获取图片,加载到内存中
        options.inJustDecodeBounds = false;
        Bitmap bitmap = BitmapFactory.decodeFile(path, options);

        return bitmap;
    }

    /**
     * 这个方法用户可以自己设置适合项目的图片比例
     *
     * @param options
     * @param reqWidth
     * @param reqHeight
     * @return
     */
    private int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
        // 源图片的宽度
        int width = options.outWidth;
        int height = options.outHeight;
        int inSampleSize = 1;

        if (width > reqWidth && height > reqHeight) // ||也是可以的,看实际情况
        {
            // 计算出实际宽度和目标宽度的比率
            int widthRatio = Math.round((float) width / (float) reqWidth);
            int heightRatio = Math.round((float) width / (float) reqWidth);
            inSampleSize = Math.max(widthRatio, heightRatio); // 为了节省内存,取了大值。如果有变形,取小值试试。
        }
        return inSampleSize;
    }
上一篇:如何终止运行中的线程


下一篇:Android把uri图片转为bitmap