生成图片的要求:图像格式采用单色位图文件格式(BMP) 要求bmp的位深度为1
参考:
关于BMP大小的计算方法:http://blog.sina.com.cn/s/blog_7136a32f0100ro5u.html
利用java实现画图板和保存读取BMP格式的图片:http://bill56.iteye.com/blog/2272044
代码有点小瑕疵 : bitmap的图片宽度要求是:8的整数倍
/**
* 将Bitmap存为 .bmp格式图片
*
* @param bitmap
*/
public void saveBmp(Bitmap bitmap) {
if (bitmap == null)
return;
// 位图大小
int nBmpWidth = bitmap.getWidth();
int nBmpHeight = bitmap.getHeight();
// 图像数据大小
int bufferSize = nBmpHeight * nBmpWidth /8 + 4*2;
try {
// 存储文件名
String filename = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "test.bmp";
File file = new File(filename);
if (!file.exists()) {
file.createNewFile();
}
FileOutputStream fileos = new FileOutputStream(filename);
// bmp文件头
int bfType = 0x4d42;
long bfSize = 14 + 40 + bufferSize;
int bfReserved1 = 0;
int bfReserved2 = 0;
long bfOffBits = 14 + 40;
// 保存bmp文件头
writeWord(fileos, bfType);
writeDword(fileos, bfSize);
writeWord(fileos, bfReserved1);
writeWord(fileos, bfReserved2);
writeDword(fileos, bfOffBits);
// bmp信息头
long biSize = 40L;
long biWidth = nBmpWidth;
long biHeight = nBmpHeight;
int biPlanes = 1;
int biBitCount = 1;
long biCompression = 0L;
long biSizeImage = 0L;
long biXpelsPerMeter = 0L;
long biYPelsPerMeter = 0L;
long biClrUsed = 0L;
long biClrImportant = 0L;
// 保存bmp信息头
writeDword(fileos, biSize);
writeLong(fileos, biWidth);
writeLong(fileos, biHeight);
writeWord(fileos, biPlanes);
writeWord(fileos, biBitCount);
writeDword(fileos, biCompression);
writeDword(fileos, biSizeImage);
writeLong(fileos, biXpelsPerMeter);
writeLong(fileos, biYPelsPerMeter);
writeDword(fileos, biClrUsed);
writeDword(fileos, biClrImportant);
//调色板
byte buf[] = new byte[]{(byte) 0xff, (byte) 0xff, (byte) 0xff,0, 0, 0, 0, 0};
fileos.write(buf);
// 像素扫描
int bw = nBmpWidth/8;
byte recv[] = new byte[bw*nBmpHeight];
int[] pixels = new int[nBmpWidth * nBmpHeight];
bitmap.getPixels(pixels, 0, nBmpWidth, 0, 0, nBmpWidth, nBmpHeight);
for(int i = nBmpHeight - 1, ii = 0; i >= 0; i--, ii++){
for(int j = 0; j < nBmpWidth; j++){
int clr = pixels[nBmpWidth * i + j];
int red = (clr & 0x00ff0000) >> 16;
int green = (clr & 0x0000ff00) >> 8;
int blue = clr & 0x000000ff;
byte gray = (RGB2Gray(red, green, blue));
recv[(nBmpWidth * ii + j) / 8] = (byte) (recv[(nBmpWidth * ii + j) / 8] | (gray << (7 - ((nBmpWidth * ii + j) % 8))));
}
}
fileos.write(recv);
fileos.flush();
fileos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private byte RGB2Gray(int r, int g, int b) {
return (false ? ((int) (0.29900 * r + 0.58700 * g + 0.11400 * b) > 200)
: ((int) (0.29900 * r + 0.58700 * g + 0.11400 * b) < 200)) ? (byte) 1 : (byte) 0;
}
protected void writeWord(FileOutputStream stream, int value) throws IOException {
byte[] b = new byte[2];
b[0] = (byte) (value & 0xff);
b[1] = (byte) (value >> 8 & 0xff);
stream.write(b);
}
protected void writeDword(FileOutputStream stream, long value) throws IOException {
byte[] b = new byte[4];
b[0] = (byte) (value & 0xff);
b[1] = (byte) (value >> 8 & 0xff);
b[2] = (byte) (value >> 16 & 0xff);
b[3] = (byte) (value >> 24 & 0xff);
stream.write(b);
}
protected void writeLong(FileOutputStream stream, long value) throws IOException {
byte[] b = new byte[4];
b[0] = (byte) (value & 0xff);
b[1] = (byte) (value >> 8 & 0xff);
b[2] = (byte) (value >> 16 & 0xff);
b[3] = (byte) (value >> 24 & 0xff);
stream.write(b);
}