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

Android Bitmap转ByteArray异常:自定义方法生成PDF显示黑图求助

Why does my Bitmap-to-byte[] conversion produce a black image in apw-android-pdf-writer?

咱们直接说核心问题:你用bitmap.compress()生成的byte数组和库的getBitmapData()输出的完全不是同一种格式,这就是PDF显示黑图的原因。

先搞懂库的方法在做什么

库的getBitmapData()是在提取原始的RGB像素流,没有任何压缩:

  • 它遍历Bitmap的每一个像素(从左到右、从上到下)
  • 每个像素用getPixel()拿到ARGB格式的int值(比如0xFFRRGGBB,前两位是Alpha通道,后面三位分别是红、绿、蓝)
  • 通过位运算把红、绿、蓝三个分量分别拆成单个字节,按顺序写入byte数组(完全忽略了Alpha通道)
  • 最终的byte数组大小是宽度 × 高度 × 3,每个像素占3个字节(R、G、B各一个)

这里的位运算其实很简单,拆解一下:

  • (intColor >> 16) & 0xFF:把int值右移16位,红色分量就落到了低8位,再和0xFF相与拿到0-255的红色值,转成byte
  • (intColor >> 8) & 0xFF:右移8位,绿色分量落到低8位,转成byte
  • (intColor >> 0) & 0xFF:蓝色分量本来就在低8位,直接转成byte

你的方法哪里错了

你用bitmap.compress(Bitmap.CompressFormat.JPEG, 80, stream)生成的是JPEG压缩后的图片文件数据,包含JPEG的文件头、压缩编码等信息,根本不是原始的RGB像素流。

当这个PDF库拿到你的byte数组时,它会把JPEG的压缩数据当成原始RGB像素来解析——这就好比你把一个Word文档当成图片打开,自然会显示成乱码(这里就是黑图)。

怎么修正你的实现

如果你想自己实现和库一样的逻辑,得按原始像素流的方式来写:

private byte[] getBitmapData(Bitmap bitmap) {
    if (bitmap != null) {
        int width = bitmap.getWidth();
        int height = bitmap.getHeight();
        byte[] data = new byte[width * height * 3];
        int offset = 0;
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                int intColor = bitmap.getPixel(x, y);
                // 提取R、G、B分量,按顺序写入数组
                data[offset++] = (byte) ((intColor >> 16) & 0xFF);
                data[offset++] = (byte) ((intColor >> 8) & 0xFF);
                data[offset++] = (byte) (intColor & 0xFF);
            }
        }
        return data;
    }
    return null;
}

注意:

  • 不要调用bitmap.recycle()在这里,除非你确定之后不再使用这个Bitmap,否则会导致空指针异常
  • 这个逻辑和库的实现完全一致,忽略了Alpha通道,如果你的Bitmap有透明区域,透明部分会被当成黑色(因为Alpha通道被丢弃,RGB部分保留原来的值)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 09:23:17