Back to index

wims  3.65+svn20090927
BMPFile.java
Go to the documentation of this file.
00001 package rene.util;
00002 
00003 import java.awt.Image;
00004 import java.awt.image.PixelGrabber;
00005 import java.io.FileOutputStream;
00006 
00007 
00018 public class BMPFile implements Runnable
00019 {
00020        
00021        //--- Private constants
00022        private final static int BITMAPFILEHEADER_SIZE = 14; 
00023        private final static int BITMAPINFOHEADER_SIZE = 40; 
00024        
00025        //--- Private variable declaration
00026        
00027        //--- Bitmap file header
00028        private byte bitmapFileHeader [] = new byte [14]; 
00029        private byte bfType [] = {  (byte)'B', (byte)'M'}; 
00030        private int bfSize = 0; 
00031        private int bfReserved1 = 0; 
00032        private int bfReserved2 = 0; 
00033        private int bfOffBits = BITMAPFILEHEADER_SIZE + BITMAPINFOHEADER_SIZE; 
00034        
00035        //--- Bitmap info header
00036        private byte bitmapInfoHeader [] = new byte [40]; 
00037        private int biSize = BITMAPINFOHEADER_SIZE; 
00038        private int biWidth = 0; 
00039        private int biHeight = 0; 
00040        private int biPlanes = 1; 
00041        private int biBitCount = 24; 
00042        private int biCompression = 0; 
00043        private int biSizeImage = 0x030000; 
00044        private int biXPelsPerMeter = 0x0; 
00045        private int biYPelsPerMeter = 0x0; 
00046        private int biClrUsed = 0; 
00047        private int biClrImportant = 0; 
00048        private int linepad = 0; 
00049        
00050        //--- Bitmap raw data
00051        private int bitmap []; 
00052        
00053        //--- File section
00054        private FileOutputStream fo; 
00055        
00056        String parFilename; 
00057        Image parImage; 
00058        int parWidth,parHeight; 
00059        
00060        public BMPFile (String parFilename, Image parImage,
00061               int parWidth, int parHeight)
00062        {      this.parFilename=parFilename; 
00063               this.parImage=parImage; 
00064               this.parWidth=parWidth; 
00065               this.parHeight=parHeight; 
00066        }
00067        
00068        public void saveBitmap ()
00069        {      run(); 
00070        }
00071        
00072        public void run ()
00073        {      try {
00074                             fo = new FileOutputStream (parFilename); 
00075                             save (parImage, parWidth, parHeight); 
00076                             fo.close (); 
00077                      }
00078                      catch (Exception saveEx) {
00079                             saveEx.printStackTrace (); 
00080                      }
00081        }
00082        
00083        /*
00084        *  The saveMethod is the main method of the process. This method
00085        *  will call the convertImage method to convert the memory image to
00086        *  a byte array; method writeBitmapFileHeader creates and writes
00087        *  the bitmap file header; writeBitmapInfoHeader creates the
00088        *  information header; and writeBitmap writes the image.
00089        *
00090        */
00091        private void save (Image parImage, int parWidth, int parHeight) {
00092               
00093               try {
00094                      convertImage (parImage, parWidth, parHeight); 
00095                      writeBitmapFileHeader (); 
00096                      writeBitmapInfoHeader (); 
00097                      writeBitmap (); 
00098               }
00099               catch (Exception saveEx) {
00100                      saveEx.printStackTrace (); 
00101               }
00102        }
00103        
00104        /*
00105        * convertImage converts the memory image to the bitmap format (BRG).
00106        * It also computes some information for the bitmap info header.
00107        *
00108        */
00109        private boolean convertImage (Image parImage, int parWidth, int parHeight)
00110        {
00111               bitmap = new int [parWidth * parHeight]; 
00112 
00113               PixelGrabber pg = new PixelGrabber (parImage, 0, 0, parWidth, parHeight,
00114                      bitmap, 0, parWidth); 
00115               
00116               try {
00117                      pg.grabPixels (); 
00118               }
00119               catch (InterruptedException e) {
00120                      e.printStackTrace (); 
00121                      return (false); 
00122               }
00123               
00124               linepad =  4 - ((parWidth * 3) % 4); 
00125               if (linepad==4) linepad=0; 
00126               biSizeImage = (parWidth * 3 +linepad) * parHeight; 
00127               bfSize = biSizeImage + BITMAPFILEHEADER_SIZE + BITMAPINFOHEADER_SIZE; 
00128               biWidth = parWidth; 
00129               biHeight = parHeight; 
00130               
00131               return (true); 
00132        }
00133        
00134        /*
00135        * writeBitmap converts the image returned from the pixel grabber to
00136        * the format required. Remember: scan lines are inverted in
00137        * a bitmap file!
00138        *
00139        * Each scan line must be padded to an even 4-byte boundary.
00140        */
00141        private void writeBitmap ()
00142        {
00143               int i,j,k; 
00144               int value; 
00145               byte rgb [] = new byte [3]; 
00146               
00147               try
00148               {      for (i=biHeight-1; i>=0; i--)
00149                      {      for (j=0; j<biWidth; j++)
00150                             {
00151                                    value = bitmap [i*biWidth+j]; 
00152                                    rgb [0] = (byte) (value & 0x000000FF); 
00153                                    rgb [1] = (byte) ((value >> 8) & 0x000000FF); 
00154                                    rgb [2] = (byte) ((value >> 16) & 0x000000FF); 
00155                                    fo.write (rgb); 
00156                             }
00157                             for (k=0; k<linepad; k++) fo.write(0x00); 
00158                      }
00159               }
00160               catch (Exception wb) {
00161                      wb.printStackTrace (); 
00162               }
00163               
00164        }
00165        
00166        /*
00167        * writeBitmapFileHeader writes the bitmap file header to the file.
00168        *
00169        */
00170        private void writeBitmapFileHeader () {
00171               
00172               try {
00173                      fo.write (bfType); 
00174                      fo.write (intToDWord (bfSize)); 
00175                      fo.write (intToWord (bfReserved1)); 
00176                      fo.write (intToWord (bfReserved2)); 
00177                      fo.write (intToDWord (bfOffBits)); 
00178                      
00179               }
00180               catch (Exception wbfh) {
00181                      wbfh.printStackTrace (); 
00182               }
00183               
00184        }
00185        
00186        /*
00187        *
00188        * writeBitmapInfoHeader writes the bitmap information header
00189        * to the file.
00190        *
00191        */
00192        
00193        private void writeBitmapInfoHeader () {
00194               
00195               try {
00196                      fo.write (intToDWord (biSize)); 
00197                      fo.write (intToDWord (biWidth)); 
00198                      fo.write (intToDWord (biHeight)); 
00199                      fo.write (intToWord (biPlanes)); 
00200                      fo.write (intToWord (biBitCount)); 
00201                      fo.write (intToDWord (biCompression)); 
00202                      fo.write (intToDWord (biSizeImage)); 
00203                      fo.write (intToDWord (biXPelsPerMeter)); 
00204                      fo.write (intToDWord (biYPelsPerMeter)); 
00205                      fo.write (intToDWord (biClrUsed)); 
00206                      fo.write (intToDWord (biClrImportant)); 
00207               }
00208               catch (Exception wbih) {
00209                      wbih.printStackTrace (); 
00210               }
00211               
00212        }
00213        
00214        /*
00215        *
00216        * intToWord converts an int to a word, where the return
00217        * value is stored in a 2-byte array.
00218        *
00219        */
00220        private byte [] intToWord (int parValue) {
00221               
00222               byte retValue [] = new byte [2]; 
00223               
00224               retValue [0] = (byte) (parValue & 0x00FF); 
00225               retValue [1] = (byte) ((parValue >> 8) & 0x00FF); 
00226               
00227               return (retValue); 
00228               
00229        }
00230        
00231        /*
00232        *
00233        * intToDWord converts an int to a double word, where the return
00234        * value is stored in a 4-byte array.
00235        *
00236        */
00237        private byte [] intToDWord (int parValue) {
00238               
00239               byte retValue [] = new byte [4]; 
00240               
00241               retValue [0] = (byte) (parValue & 0x00FF); 
00242               retValue [1] = (byte) ((parValue >> 8) & 0x000000FF); 
00243               retValue [2] = (byte) ((parValue >> 16) & 0x000000FF); 
00244               retValue [3] = (byte) ((parValue >> 24) & 0x000000FF); 
00245               
00246               return (retValue); 
00247               
00248        }
00249        
00250 }
00251