package ij.plugin;
import ij.*;
import ij.io.*;
import ij.process.*;
import java.awt.*;
import java.io.*;
import java.awt.image.*;

/** Implements the File/Save As/BMP command. Based on BMPFile class from
   http://www.javaworld.com/javaworld/javatips/jw-javatip60-p2.html */

public class BMP_Writer implements PlugIn {
 //--- Private constants
 private final static int BITMAPFILEHEADER_SIZE = 14;
 private final static int BITMAPINFOHEADER_SIZE = 40;
 //--- Private variable declaration
 //--- Bitmap file header
 private byte bitmapFileHeader [] = new byte [14];
 private byte bfType [] =  {(byte)'B', (byte)'M'};
 private int bfSize = 0;
 private int bfReserved1 = 0;
 private int bfReserved2 = 0;
 private int bfOffBits = BITMAPFILEHEADER_SIZE + BITMAPINFOHEADER_SIZE;
 //--- Bitmap info header
 private byte bitmapInfoHeader [] = new byte [40];
 private int biSize = BITMAPINFOHEADER_SIZE;
 private int biWidth = 0;
 private int padWidth = 0;
 private int biHeight = 0;
 private int biPlanes = 1;
 private int biBitCount = 24;
 private int biCompression = 0;
 private int biSizeImage = 0;
 private int biXPelsPerMeter = 0x0;
 private int biYPelsPerMeter = 0x0;
 private int biClrUsed = 0;
 private int biClrImportant = 0;
 //--- Bitmap raw data
 private int intBitmap [];
 private byte byteBitmap [];
 //--- File section
 private FileOutputStream fo;
 private BufferedOutputStream bfo;
 ImagePlus imp;

 public void run(String path) {
   IJ.showProgress(0);
   imp = WindowManager.getCurrentImage();
   if (imp==null)
     {IJ.noImage(); return;}
   try {
     writeImage(imp, path);
   } catch (Exception e) {
     String msg = e.getMessage();
     if (msg==null || msg.equals(""))
   msg = ""+e;
     IJ.error("BMP Writer", "An error occured writing the file.\n \n" + msg);
   }
   IJ.showProgress(1);
   IJ.showStatus("");
 }

 void writeImage(ImagePlus imp, String path) throws Exception {
   if(imp.getBitDepth()==24)
     biBitCount = 24;
   else {
     biBitCount = 8;
     LookUpTable lut = imp.createLut();
     biClrUsed=lut.getMapSize(); // 8 bit color image may use less
     bfOffBits+=biClrUsed*4;
   }
   if (path==null || path.equals("")) {
     String prompt = "Save as " + biBitCount + " bit BMP";
     SaveDialog sd = new SaveDialog(prompt, imp.getTitle(), ".bmp");
     if(sd.getFileName()==null)
   return;
     path = sd.getDirectory()+sd.getFileName();
   }
   imp.startTiming();
   saveBitmap (path, imp.getImage(), imp.getWidth(), imp.getHeight() );
 }


 public void saveBitmap (String parFilename, Image parImage, int parWidth, int parHeight) throws Exception {
   fo = new FileOutputStream (parFilename);
   bfo = new BufferedOutputStream(fo);
   save (parImage, parWidth, parHeight);
   bfo.close();
   fo.close ();
 }

 /*
  *   The saveMethod is the main method of the process. This method
  *   will call the convertImage method to convert the memory image to
  *   a byte array; method writeBitmapFileHeader creates and writes
  *   the bitmap file header; writeBitmapInfoHeader creates the
  *   information header; and writeBitmap writes the image.
  *
  */
 private void save (Image parImage, int parWidth, int parHeight) throws Exception {
   convertImage (parImage, parWidth, parHeight);
   writeBitmapFileHeader ();
   writeBitmapInfoHeader ();
   if(biBitCount == 8)
     writeBitmapPalette ();
   writeBitmap ();
 }

 private void writeBitmapPalette() throws Exception {
   LookUpTable lut = imp.createLut();
   byte[] g = lut.getGreens();
   byte[] r = lut.getReds();
   byte[] b = lut.getBlues();
   for(int i = 0;i0; row--) {
     if (row%20==0)
   IJ.showProgress((double)(biHeight-row)/biHeight);
     for(int col = 0; col> 8) & 0xFF);
     rgb [2] = (byte) ((value >> 16) & 0xFF);
     bfo.write(rgb);
   } else
     bfo.write(byteBitmap [(row-1)*biWidth + col ]);
   ++counter;
     }
     for (i = 1; i <= pad; i++)
   bfo.write (0x00);
     counter += pad;
   }
 }


 /*
  * writeBitmapFileHeader writes the bitmap file header to the file.
  *
  */
 private void writeBitmapFileHeader() throws Exception {
   fo.write (bfType);
   // calculate bfSize
   bfSize = bfOffBits+padWidth*biHeight;
   fo.write (intToDWord (bfSize));
   fo.write (intToWord (bfReserved1));
   fo.write (intToWord (bfReserved2));
   fo.write (intToDWord (bfOffBits));
 }

 /*
  *
  * writeBitmapInfoHeader writes the bitmap information header
  * to the file.
  *
  */
 private void writeBitmapInfoHeader () throws Exception {
   fo.write (intToDWord (biSize));
   fo.write (intToDWord (biWidth));
   fo.write (intToDWord (biHeight));
   fo.write (intToWord (biPlanes));
   fo.write (intToWord (biBitCount));
   fo.write (intToDWord (biCompression));
   fo.write (intToDWord (biSizeImage));
   fo.write (intToDWord (biXPelsPerMeter));
   fo.write (intToDWord (biYPelsPerMeter));
   fo.write (intToDWord (biClrUsed));
   fo.write (intToDWord (biClrImportant));
 }

 /*
  *
  * intToWord converts an int to a word, where the return
  * value is stored in a 2-byte array.
  *
  */
 private byte [] intToWord (int parValue) {
   byte retValue [] = new byte [2];
   retValue [0] = (byte) (parValue & 0x00FF);
   retValue [1] = (byte) ((parValue >> 8) & 0x00FF);
   return (retValue);
 }

 /*
  *
  * intToDWord converts an int to a double word, where the return
  * value is stored in a 4-byte array.
  *
  */
 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);
 }
}

 

Ads help maintain this website.