You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android中如何用Picasso加载数据库中的Bitmap图片?

解决Picasso加载Bitmap数组的问题

嘿,我懂你的困扰——Picasso的load()方法默认确实没有直接接受Bitmap对象的重载,你直接调用load(bitmapArray.get(i))肯定会报错。不过咱们有几个实用的方案,既能用上Picasso的resize、缓存这些特性,又能加载你从数据库解码出来的Bitmap数组。

方案一:将Bitmap转为ByteArrayInputStream加载

这是最快实现的方式,只需要把Bitmap转换成字节输入流,就能让Picasso识别并加载:

首先添加一个工具方法,把Bitmap转成字节数组:

private byte[] bitmapToByteArray(Bitmap bitmap) {
    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    // 这里可以根据需求改压缩格式和质量,比如JPG+80质量会更省内存
    bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
    return stream.toByteArray();
}

然后修改适配器的onBindViewHolder方法:

@Override
public void onBindViewHolder(RecyclerDataAdapter.ViewHolder viewHolder, int i) {
    Bitmap targetBitmap = bitmapArray.get(i);
    ByteArrayInputStream inputStream = new ByteArrayInputStream(bitmapToByteArray(targetBitmap));
    
    Picasso.with(context)
            .load(inputStream)
            .resize(240, 120)
            // 还可以加占位符、错误图等Picasso特性
            // .placeholder(R.drawable.loading)
            // .error(R.drawable.error)
            .into(viewHolder.img_android);
}

这种方式的好处是快速上手,不需要额外的类,但每次都要压缩Bitmap,对性能有一点点影响,适合小范围使用。

方案二:自定义RequestHandler扩展Picasso(推荐复用场景)

如果你的项目里经常需要用Picasso加载Bitmap,那自定义一个RequestHandler会更优雅,相当于给Picasso增加了直接加载Bitmap的能力:

首先创建一个BitmapRequestHandler类:

public class BitmapRequestHandler extends RequestHandler {
    // 自定义一个Uri协议,用来标识这是Bitmap请求
    private static final String SCHEME_BITMAP = "bitmap";

    @Override
    public boolean canHandleRequest(Request data) {
        // 判断是否是我们自定义的Bitmap请求
        return SCHEME_BITMAP.equals(data.uri.getScheme());
    }

    @Override
    public Result load(Request request, int networkPolicy) throws IOException {
        // 从tag中取出Bitmap对象
        Bitmap bitmap = (Bitmap) request.tag;
        // 返回加载结果,标记为从磁盘加载(也可以根据实际情况改)
        return new Result(bitmap, Picasso.LoadedFrom.DISK);
    }

    // 生成对应的Uri,用来告诉Picasso用我们的Handler处理
    public static Uri createBitmapUri(Bitmap bitmap) {
        return new Uri.Builder()
                .scheme(SCHEME_BITMAP)
                // 用Bitmap的哈希值作为host,确保Uri唯一
                .host(String.valueOf(bitmap.hashCode()))
                .build();
    }
}

然后在你的Application初始化或者第一次使用Picasso的地方,注册这个Handler:

// 全局注册,一次注册到处能用
Picasso picasso = Picasso.with(getApplicationContext());
picasso.addRequestHandler(new BitmapRequestHandler());

最后修改适配器的加载逻辑:

@Override
public void onBindViewHolder(RecyclerDataAdapter.ViewHolder viewHolder, int i) {
    Bitmap targetBitmap = bitmapArray.get(i);
    
    Picasso.with(context)
            .load(BitmapRequestHandler.createBitmapUri(targetBitmap))
            .tag(targetBitmap) // 把Bitmap作为tag传进去
            .resize(240, 120)
            .into(viewHolder.img_android);
}

这个方案的优势是扩展性强,以后任何地方都能直接用Picasso加载Bitmap,还能充分利用Picasso的缓存机制,适合频繁使用的场景。

方案三:直接用ImageView显示(无需Picasso额外功能)

如果你只是想显示Bitmap,不需要Picasso的占位符、内存缓存等特性,那直接用ImageView的setImageBitmap最直接,还能省掉Picasso的转换开销:

@Override
public void onBindViewHolder(RecyclerDataAdapter.ViewHolder viewHolder, int i) {
    Bitmap targetBitmap = bitmapArray.get(i);
    // 先对Bitmap进行缩放,达到你要的240x120尺寸
    Bitmap resizedBitmap = Bitmap.createScaledBitmap(targetBitmap, 240, 120, true);
    viewHolder.img_android.setImageBitmap(resizedBitmap);
}

不过要注意,这种方式需要自己管理Bitmap的内存,避免在RecyclerView滑动时出现内存泄漏或者OOM,最好配合Bitmap的回收机制使用。


内容的提问来源于stack exchange,提问作者gorp88

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:43:50