Volley ImageLoader加载本地图片特别版

最近项目中用到gridView显示图片,一开始自然而然的就想到显示图片用Android-Universal-Image-Loader,结果在gridview中却发现不能显示本地图片,试了多次还是不知道什么原因;如果布局文件中单独的一个imageview调用imageLoader却可以正常显示。说明我的imageLoader配置没错,很有可能这个框架和gridview结合并且加载本地图片有问题。所以我就打算自己写一个工具专门用来加载本地图片。动手之前突然想到google的volley也有一个加载图片的工具类,只不过volley只适合加载网络图片。所以就想到借用volley的图片解析方法自己写一个图片加载工具,哈哈,是不是很好。

代码呈上:

package com.hai.utils;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.widget.ImageView;

/**
 * Created by 黄海 on 2016/1/20.
 */
public class ImageLoader {
    /**
     * 解析本地图片
     *
     * @param url           本地图片文件目录
     * @param mMaxWidth
     * @param mMaxHeight
     * @param mScaleType
     * @param mDecodeConfig
     * @return
     */
    public static Bitmap parseFile(String url, int mMaxWidth, int mMaxHeight, ImageView.ScaleType mScaleType, Bitmap.Config mDecodeConfig) {
//        byte[] data = response.data;
        BitmapFactory.Options decodeOptions = new BitmapFactory.Options();
        Bitmap bitmap = null;
        if (mMaxWidth == 0 && mMaxHeight == 0) {
            decodeOptions.inPreferredConfig = mDecodeConfig;
            //原来是解析网络请求返回的字节数组
//            bitmap = BitmapFactory.decodeByteArray(data, 0, data.length, decodeOptions);
            bitmap = BitmapFactory.decodeFile(url, decodeOptions);
        } else {
            // If we have to resize this image, first get the natural bounds.
            decodeOptions.inJustDecodeBounds = true;
            BitmapFactory.decodeFile(url, decodeOptions);
            int actualWidth = decodeOptions.outWidth;
            int actualHeight = decodeOptions.outHeight;

            // Then compute the dimensions we would ideally like to decode to.
            int desiredWidth = getResizedDimension(mMaxWidth, mMaxHeight,
                    actualWidth, actualHeight, mScaleType);
            int desiredHeight = getResizedDimension(mMaxHeight, mMaxWidth,
                    actualHeight, actualWidth, mScaleType);

            // Decode to the nearest power of two scaling factor.
            decodeOptions.inJustDecodeBounds = false;
            // TODO(ficus): Do we need this or is it okay since API 8 doesn't support it?
            // decodeOptions.inPreferQualityOverSpeed = PREFER_QUALITY_OVER_SPEED;
            decodeOptions.inSampleSize =
                    findBestSampleSize(actualWidth, actualHeight, desiredWidth, desiredHeight);
//            Bitmap tempBitmap =
//                    BitmapFactory.decodeByteArray(data, 0, data.length, decodeOptions);
            Bitmap tempBitmap =
                    BitmapFactory.decodeFile(url, decodeOptions);
            // If necessary, scale down to the maximal acceptable size.
            if (tempBitmap != null && (tempBitmap.getWidth() > desiredWidth ||
                    tempBitmap.getHeight() > desiredHeight)) {
                bitmap = Bitmap.createScaledBitmap(tempBitmap,
                        desiredWidth, desiredHeight, true);
                tempBitmap.recycle();
            } else {
                bitmap = tempBitmap;
            }
        }
        return bitmap;
    }

    /**
     * 获取期望的width和heigth
     *
     * @param maxPrimary
     * @param maxSecondary
     * @param actualPrimary
     * @param actualSecondary
     * @param scaleType
     * @return
     */
    private static int getResizedDimension(int maxPrimary, int maxSecondary, int actualPrimary,
                                           int actualSecondary, ImageView.ScaleType scaleType) {

        // If no dominant value at all, just return the actual.
        if ((maxPrimary == 0) && (maxSecondary == 0)) {
            return actualPrimary;
        }

        // If ScaleType.FIT_XY fill the whole rectangle, ignore ratio.
        if (scaleType == ImageView.ScaleType.FIT_XY) {
            if (maxPrimary == 0) {
                return actualPrimary;
            }
            return maxPrimary;
        }

        // If primary is unspecified, scale primary to match secondary's scaling ratio.
        if (maxPrimary == 0) {
            double ratio = (double) maxSecondary / (double) actualSecondary;
            return (int) (actualPrimary * ratio);
        }

        if (maxSecondary == 0) {
            return maxPrimary;
        }

        double ratio = (double) actualSecondary / (double) actualPrimary;
        int resized = maxPrimary;

        // If ScaleType.CENTER_CROP fill the whole rectangle, preserve aspect ratio.
        if (scaleType == ImageView.ScaleType.CENTER_CROP) {
            if ((resized * ratio) < maxSecondary) {
                resized = (int) (maxSecondary / ratio);
            }
            return resized;
        }

        if ((resized * ratio) > maxSecondary) {
            resized = (int) (maxSecondary / ratio);
        }
        return resized;
    }

    /**
     * 计算缩放比例
     *
     * @param actualWidth
     * @param actualHeight
     * @param desiredWidth
     * @param desiredHeight
     * @return
     */
    static int findBestSampleSize(
            int actualWidth, int actualHeight, int desiredWidth, int desiredHeight) {
        double wr = (double) actualWidth / desiredWidth;
        double hr = (double) actualHeight / desiredHeight;
        double ratio = Math.min(wr, hr);
        float n = 1.0f;
        while ((n * 2) <= ratio) {
            n *= 2;
        }
        return (int) n;
    }
}

我写的这个imageloader的图片解析代码基本是借用volley的ImageRequest中的代码,两者的区别在于一个是用于加载本地图片,一个加载网络图片。

文中我提到两点:

  • Universal-Image-Loader,和gridview结合不好用,常不能显示本地图片
  • volley的图片加载也不适用与本地图片

    不知大家是否认同我的这两点,如果不认同,还请指正

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值