我正在尝试将包含24位位图文件数据的字节数组加载到Android中的Bitmap对象中,但我遇到了麻烦,因为Bitmap只支持32位和16位格式。以下是我为了将24位数据转换为32位而想出的内容:
byte[] file = new byte[is.available()];
is.read(file);
is.close();
byte[] paddedFile = new byte[file.length + file.length / 3]; //we will be adding 1 more byte (alpha value) for each RGB triplet
for (int i = 0; i < file.length / 3; i++) {
paddedFile[i * 4] = file[i * 3];
paddedFile[i * 4 + 1] = file[i * 3 + 1];
paddedFile[i * 4 + 2] = file[i * 3 + 2];
paddedFile[i * 4 + 3] = -1; //manually added alpha channel
}
Bitmap screen = Bitmap.createBitmap(479, 616, Bitmap.Config.ARGB_8888); //exact dimensions of the 24-bit bitmap file
screen.copyPixelsFromBuffer(ByteBuffer.wrap(paddedFile));
iv.setImageBitmap(screen);
它几乎/几乎有效。这是我正在使用的位图:
这就是上面代码后出现的内容:
为什么会扭曲?任何关于如何解决这个问题的线索都非常感谢。
答案 0 :(得分:2)
如果我对填充是正确的,你应该可以这样做:
int w = 479;
int h = 616;
byte[] file = /* as before */;
// Convert interleaved byte RGB to packed int ARGB
int[] paddedFile = new int[file.length / 3];
for (int i = 0; i < file.length / 3; i++) {
paddedFile[i] = 0xff << 24 // Alpha (all opaque)
| ((file[i * 3] & 0xff) << 16)
| ((file[i * 3 + 1] & 0xff) << 8)
| ((file[i * 3 + 2] & 0xff))
}
int stride = w + (w % 4 == 0 ? 0 : 4 - (w % 4));
Bitmap screen = Bitmap.createBitmap(paddedFile, 0, stride, w, h, Bitmap.Config.ARGB_8888);
答案 1 :(得分:0)
在haraldK的评论之后,我已经登陆Wikipedia page关于位图格式,我已经知道位图字节数组基本上是行*高度。行包含的字节数通过以下公式计算:
int paddedRow = (int) Math.floor((24 * w + 31) / 32) * 4; //1440 bytes
考虑到这是一个24位(3字节)位图,每行的实际数据量是:
int actualRow = 3 * w; //1437 bytes
因此每行的填充量为:
int padding = paddedRow - actualRow; //3 bytes
这意味着1440行的每个最后3个字节都是填充(其中有616个)。知道这些值后,我们可以从字节数组中提取真实的颜色数据,然后正确附加alpha通道:
byte[] file = new byte[is.available()];
is.read(file);
is.close();
int w = 479;
int h = 616;
int paddedRow = (int) Math.floor((24 * w + 31) / 32) * 4;
int actualRow = 3 * w;
int padding = paddedRow - actualRow;
byte[] removedPadding = new byte[file.length - padding * h];
for (int j = 0, k = 0; j < h; j++) {
int tmp = j * paddedRow;
for (int i = 0 + tmp; i < actualRow + tmp; i++, k++) {
removedPadding[k] = file[i];
}
}
byte[] rgbaFile = new byte[removedPadding.length + removedPadding.length / 3];
for (int i = 0; i < removedPadding.length / 3; i++) {
rgbaFile[i * 4] = removedPadding[i * 3];
rgbaFile[i * 4 + 1] = removedPadding[i * 3 + 1];
rgbaFile[i * 4 + 2] = removedPadding[i * 3 + 2];
rgbaFile[i * 4 + 3] = -1;
}
Bitmap screen = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
screen.copyPixelsFromBuffer(ByteBuffer.wrap(rgbaFile));
iv.setImageBitmap(screen);