将Android Bitmap对象转换为8位BMP文件的代码。
这是从以下C#项目中衍生而来的:https://www.codeproject.com/articles/70442/c-rgb-to-palette-based-bit-greyscale-bitmap-clas
import android.graphics.Bitmap;
import android.graphics.Color;
public class BitmapConvertor {
private byte[] Color_palette = new byte[1024];
private byte[] BMP_File_Header = new byte[14];
private byte[] DIB_header = new byte[40];
private byte[] Bitmap_Data = null;
public byte[] CreateGrayBitmapArray(Bitmap Image) {
try {
create_parts(Image);
byte[] bitmap_array = new byte[BMP_File_Header.length + DIB_header.length
+ Color_palette.length + Bitmap_Data.length];
Copy_to_Index(bitmap_array, BMP_File_Header, 0);
Copy_to_Index(bitmap_array, DIB_header, BMP_File_Header.length);
Copy_to_Index(bitmap_array, Color_palette, BMP_File_Header.length + DIB_header.length);
Copy_to_Index(bitmap_array, Bitmap_Data, BMP_File_Header.length + DIB_header.length + Color_palette.length);
return bitmap_array;
} catch (Exception e) {
return null;
}
}
private byte[] create_palette() {
byte[] color_palette = new byte[1024];
for (int i = 0; i < 256; i++) {
color_palette[i * 4 + 0] = (byte) (i);
color_palette[i * 4 + 1] = (byte) (i);
color_palette[i * 4 + 2] = (byte) (i);
color_palette[i * 4 + 3] = (byte) 0;
}
return color_palette;
}
private boolean Copy_to_Index(byte[] destination, byte[] source, int index) {
try {
for (int i = 0; i < source.length; i++) {
destination[i + index] = source[i];
}
return true;
} catch (Exception e) {
return false;
}
}
private void create_parts(Bitmap img) {
Bitmap_Data = ConvertToGrayscale(img);
Copy_to_Index(BMP_File_Header, new byte[]{(byte) 'B', (byte) 'M'}, 0);
Copy_to_Index(BMP_File_Header, writeInt(BMP_File_Header.length
+ DIB_header.length + Color_palette.length + Bitmap_Data.length), 2);
Copy_to_Index(BMP_File_Header, new byte[]{(byte) 'M', (byte) 'C', (byte) 'A', (byte) 'T'}, 6);
Copy_to_Index(BMP_File_Header, writeInt(BMP_File_Header.length
+ DIB_header.length + Color_palette.length), 10);
Copy_to_Index(DIB_header, writeInt(DIB_header.length), 0);
Copy_to_Index(DIB_header, writeInt(((Bitmap) img).getWidth()), 4);
Copy_to_Index(DIB_header, writeInt(((Bitmap) img).getHeight()), 8);
Copy_to_Index(DIB_header, new byte[]{(byte) 1, (byte) 0}, 12);
Copy_to_Index(DIB_header, new byte[]{(byte) 8, (byte) 0}, 14);
Copy_to_Index(DIB_header, writeInt(0), 16);
Copy_to_Index(DIB_header, writeInt(Bitmap_Data.length), 20);
Copy_to_Index(DIB_header, writeInt(1000), 24);
Copy_to_Index(DIB_header, writeInt(1000), 28);
Copy_to_Index(DIB_header, writeInt(256), 32);
Copy_to_Index(DIB_header, writeInt(0), 36);
Color_palette = create_palette();
}
private byte[] ConvertToGrayscale(Bitmap Source) {
Bitmap source = (Bitmap) Source;
int padding = (source.getWidth() % 4) != 0 ? 4 - (source.getWidth() % 4) : 0;
byte[] bytes = new byte[source.getWidth() * source.getHeight() + padding * source.getHeight()];
for (int y = 0; y < source.getHeight(); y++) {
for (int x = 0; x < source.getWidth(); x++) {
int pixel = source.getPixel(x, y);
int g = (int) (0.3 * Color.red(pixel) + 0.59 * Color.green(pixel) + 0.11 * Color.blue(pixel));
bytes[(source.getHeight() - 1 - y) * source.getWidth() + (source.getHeight() - 1 - y) * padding + x] = (byte) g;
}
for (int i = 0; i < padding; i++) {
bytes[(source.getHeight() - y) * source.getWidth() + (source.getHeight() - 1 - y) * padding + i] = (byte) 0;
}
}
return bytes;
}
private byte[] writeInt(int value) {
byte[] b = new byte[4];
b[0] = (byte) (value & 0x000000FF);
b[1] = (byte) ((value & 0x0000FF00) >> 8);
b[2] = (byte) ((value & 0x00FF0000) >> 16);
b[3] = (byte) ((value & 0xFF000000) >> 24);
return b;
}
}