[摘要]FFFF FFFF FFFF FFFF FFFF0000000100 FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF* 在,我们开始检视代码 现在我们已经知道了 2... FFFF FFFF FFFF FFFF FFFF 0000000100 FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF *
在,我们开始检视代码
现在我们已经知道了 24 位位图文件的结构,下面就是您期待已久的内容:用来将图像对象写入位图文件的代码。 import java.awt.*; import java.io.*; import java.awt.image.*;
public class BMPFile extends Component {
file://--- 私有常量 private final static int BITMAPFILEHEADER_SIZE = 14; private final static int BITMAPINFOHEADER_SIZE = 40;
file://--- 私有变量声明
file://--- 位图文件标头 private byte bitmapFileHeader [] = new byte [14]; private byte bfType [] = {'B', 'M'}; private int bfSize = 0; private int bfReserved1 = 0; private int bfReserved2 = 0; private int bfOffBits = BITMAPFILEHEADER_SIZE + BITMAPINFOHEADER_SIZE;
file://--- 位图信息标头 private byte bitmapInfoHeader [] = new byte [40]; private int biSize = BITMAPINFOHEADER_SIZE; private int biWidth = 0; private int biHeight = 0; private int biPlanes = 1; private int biBitCount = 24; private int biComdivssion = 0; private int biSizeImage = 0x030000; private int biXPelsPerMeter = 0x0; private int biYPelsPerMeter = 0x0; private int biClrUsed = 0; private int biClrImportant = 0;
file://--- 位图原始数据 private int bitmap [];
file://--- 文件部分 private FileOutputStream fo;
file://--- 缺省构造函数 public BMPFile() {
}
public void saveBitmap (String parFilename, Image parImage, int parWidth, int parHeight) {
try { fo = new FileOutputStream (parFilename); save (parImage, parWidth, parHeight); fo.close (); } catch (Exception saveEx) { saveEx.printStackTrace (); }
}
/* * saveMethod 是该进程的主方法。该方法 * 将调用 convertImage 方法以将内存图像转换为 * 字节数组;writeBitmapFileHeader 方法创建并写入 * 位图文件标头;writeBitmapInfoHeader 创建 * 信息标头;writeBitmap 写入图像。 * */ private void save (Image parImage, int parWidth, int parHeight) {
try { convertImage (parImage, parWidth, parHeight); writeBitmapFileHeader (); writeBitmapInfoHeader (); writeBitmap (); } catch (Exception saveEx) { saveEx.printStackTrace (); } }
/* * convertImage 将内存图像转换为位图格式 (BRG)。 * 它还计算位图信息标头所用的某些信息。 * */ private boolean convertImage (Image parImage, int parWidth, int parHeight) {
int pad; bitmap = new int [parWidth * parHeight];
PixelGrabber pg = new PixelGrabber (parImage, 0, 0, parWidth, parHeight, bitmap, 0, parWidth);
try { pg.grabPixels (); } catch (InterruptedException e) { e.printStackTrace (); return (false); }
pad = (4 - ((parWidth * 3) % 4)) * parHeight; biSizeImage = ((parWidth * parHeight) * 3) + pad; bfSize = biSizeImage + BITMAPFILEHEADER_SIZE + BITMAPINFOHEADER_SIZE; biWidth = parWidth; biHeight = parHeight;
return (true); }
/* * writeBitmap 将象素捕获器返回的图像转换为 * 所需的格式。请记住:扫描行在位图文件中是 * 反向存储的! * * 每个扫描行必须补足为 4 个字节。 */ private void writeBitmap () {
int size; int value; int j; int i; int rowCount; int rowIndex; int lastRowIndex; int pad; int padCount; byte rgb [] = new byte [3];
size = (biWidth * biHeight) - 1; pad = 4 - ((biWidth * 3) % 4); if (pad == 4) // <==== 错误修正 pad = 0; // <==== 错误修正 rowCount = 1; padCount = 0; rowIndex = size - biWidth; lastRowIndex = rowIndex;
try { for (j = 0; j < size; j++) { value = bitmap [rowIndex]; rgb [0] = (byte) (value & 0xFF); rgb [1] = (byte) ((value >> 8) & 0xFF); rgb [2] = (byte) ((value >> 16) & 0xFF); fo.write (rgb); if (rowCount == biWidth) { padCount += pad; for (i = 1; i <= pad; i++) { fo.write (0x00); } rowCount = 1; rowIndex = lastRowIndex - biWidth; lastRowIndex = rowIndex; } else rowCount++; rowIndex++; }
file://--- 更新文件大小 bfSize += padCount - pad; biSizeImage += padCount - pad; } catch (Exception wb) { wb.printStackTrace (); }
}
/* * writeBitmapFileHeader 将位图文件标头写入文件中。 * */ private void writeBitmapFileHeader () {
try { fo.write (bfType); fo.write (intToDWord (bfSize)); fo.write (intToWord (bfReserved1)); fo.write (intToWord (bfReserved2)); fo.write (intToDWord (bfOffBits));
} catch (Exception wbfh) { wbfh.printStackTrace (); }
}
/* * * writeBitmapInfoHeader 将位图信息标头 * 写入文件中。 * */
private void writeBitmapInfoHeader () {
try { fo.write (intToDWord (biSize)); fo.write (intToDWord (biWidth)); fo.write (intToDWord (biHeight)); fo.write (intToWord (biPlanes)); fo.write (intToWord (biBitCount)); fo.write (intToDWord (biComdivssion)); fo.write (intToDWord (biSizeImage)); fo.write (intToDWord (biXPelsPerMeter)); fo.write (intToDWord (biYPelsPerMeter)); fo.write (intToDWord (biClrUsed)); fo.write (intToDWord (biClrImportant)); } catch (Exception wbih) { wbih.printStackTrace (); }
}
/* * * intToWord 将整数转换为单字,返回值 * 存储在一个双字节数组中。 * */ private byte [] intToWord (int parValue) {
byte retValue [] = new byte [2];
retValue [0] = (byte) (parValue & 0x00FF); retValue [1] = (byte) ((parValue >> 8) & 0x00FF);
return (retValue);
}
/* * * intToDWord 将整数转换为双字,返回值 * 存储在一个 4 字节数组中。 * */ private byte [] intToDWord (int parValue) {
byte retValue [] = new byte [4];
retValue [0] = (byte) (parValue & 0x00FF); retValue [1] = (byte) ((parValue >> 8) & 0x000000FF); retValue [2] = (byte) ((parValue >> 16) & 0x000000FF); retValue [3] = (byte) ((parValue >> 24) & 0x000000FF);
return (retValue);
}
}
小结
这就是所要做的全部工作。我确信您将会发现这个类很有用,因为到 JDK 1.1.6 为止,Java 不支持用任何常用的格式保存图像。JDK 1.2 将支持创建 JPEG 图像,但不支持创建位图。所以这个类仍将填补 JDK1.2 中的空白。
|