本地图片转bitmap

在项目中将本地图片显示到imageview时,遇到Bitmap转换问题。原有的convertToBitmap方法可能导致空指针错误。文章提供了两种可行的解决方案:1) 使用compressImageFromFile方法通过设置采样率来压缩图片;2) 使用ImageUtils的asyncLoadImage异步加载图片,并在回调中获取Bitmap。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

项目中需要用imageview显示本地图片,参考别人的博客。

网上有一个方法,试了下,会报空指针:如下

public Bitmap convertToBitmap(String path, int w, int h) {
BitmapFactory.Options opts = new BitmapFactory.Options();
// 设置为ture只获取图片大小
opts.inJustDecodeBounds = true;
opts.inPreferredConfig = Bitmap.Config.ARGB_8888;
// 返回为空
BitmapFactory.decodeFile(path, opts);
int width = opts.outWidth;
int height = opts.outHeight;
float scaleWidth = 0.f, scaleHeight = 0.f;
if (width > w || height > h) {
// 缩放
scaleWidth = ((float) width) / w;
scaleHeight = ((float) height) / h;
}
opts.inJustDecodeBounds = false;
float scale = Math.max(scaleWidth, scaleHeight);
opts.inSampleSize = (int)scale;
WeakReference weak = new WeakReference(BitmapFactory.decodeFile(path, opts));
return Bitmap.createScaledBitmap(weak.get(), w, h, true);
}
多试几次就会报错。

以下两个方法可以用:
1.
/**
* 将图片从本地读到内存时,进行压缩 ,即图片从File形式变为Bitmap形式
* 特点: 通过设置采样率, 减少图片的像素, 达到对内存中的Bitmap进行压缩
* @param srcPath
* @return
*/
public static Bitmap compressImageFromFile(String srcPath, float pixWidth, float pixHeight) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;// 只读边,不读内容
Bitmap bitmap = BitmapFactory.decodeFile(srcPath, options);

    options.inJustDecodeBounds = false;
    int w = options.outWidth;
    int h = options.outHeight;
    int scale = 1;
    if (w > h && w > pixWidth) {
        scale = (int) (options.outWidth / pixWidth);
    } else if (w < h && h > pixHeight) {
        scale = (int) (options.outHeight / pixHeight);
    }
    if (scale <= 0)
        scale = 1;
    options.inSampleSize = scale;// 设置采样率

    options.inPreferredConfig = Bitmap.Config.ARGB_8888;// 该模式是默认的,可不设
    options.inPurgeable = true;// 同时设置才会有效
    options.inInputShareable = true;// 。当系统内存不够时候图片自动被回收

    bitmap = BitmapFactory.decodeFile(srcPath, options);
    // return compressBmpFromBmp(bitmap);//原来的方法调用了这个方法企图进行二次压缩
    // 其实是无效的,大家尽管尝试
    return bitmap;
}

2.
imagePath 是图片等本地路径 ,例如 /storage/emulated/0/album_2016-11-23_12:12:11.jpg
Uri targetUri = Uri.fromFile(new File(imagePath));
ImageUtils.asyncLoadImage(this, targetUri, new ImageUtils.LoadImageCallback() {
@Override
public void callback(Bitmap bitmap) {
shareBitmap = bitmap;
}
});

public class ImageUtils {

public static int getMiniSize(String imagePath) {
    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(imagePath, options);
    return Math.min(options.outHeight, options.outWidth);
}

public static int isSquare(String imagePath) {
    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(imagePath, options);
    return options.outHeight - options.outWidth;
}

//图片是不是正方形
public static int isSquare(Uri imageUri) {
    ContentResolver resolver = BMApplication.getInstance().getContentResolver();
    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    try {
        BitmapFactory.decodeStream(resolver.openInputStream(imageUri), null, options);
    } catch (Exception e) {
        e.printStackTrace();
        return 1;
    }
    return options.outHeight - options.outWidth;
}

public static void asyncSaveToFile(String fileFolderStr, Bitmap croppedImage, SaveImageCallback callback) {
    new SaveImageTask(fileFolderStr, croppedImage, callback).execute();
}
//保存图片文件
public static String saveToFile(String fileFolderStr, boolean isDir, Bitmap croppedImage) throws FileNotFoundException, IOException {
    File jpgFile;
    if (isDir) {
        File fileFolder = new File(fileFolderStr);
        Date date = new Date();
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss"); // 格式化时间
        String filename = format.format(date) + ".jpg";
        if (!fileFolder.exists()) { // 如果目录不存在,则创建一个名为"finger"的目录
            FileUtils.getInst().mkdir(fileFolder);
        }
        jpgFile = new File(fileFolder, filename);
    } else {
        jpgFile = new File(fileFolderStr);
        if (!jpgFile.getParentFile().exists()) { // 如果目录不存在,则创建一个名为"finger"的目录
            FileUtils.getInst().mkdir(jpgFile.getParentFile());
        }
    }
    FileOutputStream outputStream = new FileOutputStream(jpgFile); // 文件输出流

    croppedImage.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
    IOUtil.closeStream(outputStream);
    return jpgFile.getPath();
}



//从文件中读取Bitmap
public static Bitmap decodeBitmapWithOrientation(String pathName, int width, int height) {
    return decodeBitmapWithSize(pathName, width, height, false);
}

public static Bitmap decodeBitmapWithOrientationMax(String pathName, int width, int height) {
    return decodeBitmapWithSize(pathName, width, height, true);
}

private static Bitmap decodeBitmapWithSize(String pathName, int width, int height,
                                           boolean useBigger) {
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    options.inInputShareable = true;
    options.inPurgeable = true;
    BitmapFactory.decodeFile(pathName, options);

    int decodeWidth = width, decodeHeight = height;
    final int degrees = getImageDegrees(pathName);
    if (degrees == 90 || degrees == 270) {
        decodeWidth = height;
        decodeHeight = width;
    }

    if (useBigger) {
        options.inSampleSize = (int) Math.min(((float) options.outWidth / decodeWidth),
                ((float) options.outHeight / decodeHeight));
    } else {
        options.inSampleSize = (int) Math.max(((float) options.outWidth / decodeWidth),
                ((float) options.outHeight / decodeHeight));
    }

    options.inJustDecodeBounds = false;
    Bitmap sourceBm = BitmapFactory.decodeFile(pathName, options);
    return imageWithFixedRotation(sourceBm, degrees);
}

public static int getImageDegrees(String pathName) {
    int degrees = 0;
    try {
        ExifInterface exifInterface = new ExifInterface(pathName);
        int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION,
                ExifInterface.ORIENTATION_NORMAL);
        switch (orientation) {
            case ExifInterface.ORIENTATION_ROTATE_90:
                degrees = 90;
                break;
            case ExifInterface.ORIENTATION_ROTATE_180:
                degrees = 180;
                break;
            case ExifInterface.ORIENTATION_ROTATE_270:
                degrees = 270;
                break;
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return degrees;
}

public static Bitmap imageWithFixedRotation(Bitmap bm, int degrees) {
    if (bm == null || bm.isRecycled())
        return null;

    if (degrees == 0)
        return bm;

    final Matrix matrix = new Matrix();
    matrix.postRotate(degrees);
    Bitmap result = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), matrix, true);
    if (result != bm)
        bm.recycle();
    return result;

}


public static float getImageRadio(ContentResolver resolver, Uri fileUri) {
    InputStream inputStream = null;
    try {
        inputStream = resolver.openInputStream(fileUri);
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(inputStream, null, options);
        int initWidth = options.outWidth;
        int initHeight = options.outHeight;
        float rate = initHeight > initWidth ? (float) initHeight / (float) initWidth
                : (float) initWidth / (float) initHeight;
        return rate;
    } catch (Exception e) {
        e.printStackTrace();
        return 1;
    } finally {
        IOUtil.closeStream(inputStream);
    }
}

public static Bitmap byteToBitmap(byte[] imgByte) {
    InputStream input = null;
    Bitmap bitmap = null;
    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inSampleSize = 1;
    input = new ByteArrayInputStream(imgByte);
    SoftReference softRef = new SoftReference(BitmapFactory.decodeStream(
            input, null, options));
    bitmap = (Bitmap) softRef.get();
    if (imgByte != null) {
        imgByte = null;
    }

    try {
        if (input != null) {
            input.close();
        }
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return bitmap;
}

//异步加载图片
public static interface LoadImageCallback {
    public void callback(Bitmap result);
}
//异步保存图片
public interface SaveImageCallback{
    void callback(String path);
}

public static void asyncLoadImage(Context context, Uri imageUri, LoadImageCallback callback) {
    new LoadImageUriTask(context, imageUri, callback).execute();
}

private static class LoadImageUriTask extends AsyncTask<Void, Void, Bitmap> {
    private final Uri         imageUri;
    private final Context     context;
    private LoadImageCallback callback;

    public LoadImageUriTask(Context context, Uri imageUri, LoadImageCallback callback) {
        this.imageUri = imageUri;
        this.context = context;
        this.callback = callback;
    }

    @Override
    protected Bitmap doInBackground(Void... params) {
        try {
            InputStream inputStream;
            if (imageUri.getScheme().startsWith("http")
                    || imageUri.getScheme().startsWith("https")) {
                inputStream = new URL(imageUri.toString()).openStream();
            } else {
                inputStream = context.getContentResolver().openInputStream(imageUri);
            }
            return BitmapFactory.decodeStream(inputStream);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onPostExecute(Bitmap result) {
        super.onPostExecute(result);
        callback.callback(result);
    }
}

//异步加载缩略图
public static void asyncLoadSmallImage(Context context, Uri imageUri, int width, int height, LoadImageCallback callback) {
    new LoadSmallPicTask(context, imageUri, callback, width, height).execute();
}

private static class LoadSmallPicTask extends AsyncTask<Void, Void, Bitmap> {

    private final Uri         imageUri;
    private final Context     context;
    private LoadImageCallback callback;
    private final int width;
    private final int height;

    public LoadSmallPicTask(Context context, Uri imageUri, LoadImageCallback callback, int width, int height) {
        this.imageUri = imageUri;
        this.context = context;
        this.callback = callback;
        this.width = width;
        this.height = height;
    }

    @Override
    protected Bitmap doInBackground(Void... params) {
        return getResizedBitmap(context, imageUri, width, height);
    }

    @Override
    protected void onPostExecute(Bitmap result) {
        super.onPostExecute(result);
        callback.callback(result);
    }

}

//得到指定大小的Bitmap对象
public static Bitmap getResizedBitmap(Context context, Uri imageUri, int width, int height) {
    InputStream inputStream = null;
    try {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;

        inputStream = context.getContentResolver().openInputStream(imageUri);
        BitmapFactory.decodeStream(inputStream, null, options);

        options.inJustDecodeBounds = false;
        int targetRate = (int) Math.ceil(1.0f * options.outWidth / width);
        options.inSampleSize = targetRate <= 1 ? 1 : targetRate;
        IOUtil.closeStream(inputStream);
        inputStream = context.getContentResolver().openInputStream(imageUri);
        return BitmapFactory.decodeStream(inputStream, null, options);
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        IOUtil.closeStream(inputStream);
    }
    return null;
}

public static class AsyncLoadImageWithGPUFiltersTask extends AsyncTask<Void, Void, Bitmap> {

    private final Bitmap src;
    private final GPUImageFilter filter;
    private final GPUImage gpuImage;
    private final LoadImageCallback callback;

    public AsyncLoadImageWithGPUFiltersTask(Context context, Bitmap src, GPUImageFilter filter, LoadImageCallback callback) {
        this.src = src;
        this.filter = filter;
        this.callback = callback;
        gpuImage = new GPUImage(context);
    }

    @Override
    protected void onPostExecute(Bitmap bitmap) {
        callback.callback(bitmap);
    }

    @Override
    protected Bitmap doInBackground(Void... params) {
        gpuImage.setImage(src);
        gpuImage.setFilter(filter);
        return gpuImage.getBitmapWithFilterApplied();
    }
}
private static class SaveImageTask extends AsyncTask<Void, Void, String> {
    private final String      targetPath;
    private SaveImageCallback callback;
    private final Bitmap      src;

    public SaveImageTask(String targetPath, Bitmap src, SaveImageCallback callback) {
        this.targetPath = targetPath;
        this.callback = callback;
        this.src = src;
    }

    @Override
    protected String doInBackground(Void... params) {
        try {
            return saveToFile(targetPath, false, src);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onPostExecute(String result) {
        callback.callback(result);
    }
}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值