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
相关产品推荐
相关产品推荐

