Save bitmap file with Java

zhaozj2021-02-11  225

Save bitmap file with Java Jean-Pierre Dubé · JDeveloper

Abstract Although Java provides several mechanisms that open images, the save image is not its strength. This trick will tell how to save images in a 24-bit bitmap file. In addition, Jean-Pierre provides all code required to write image files to the bitmap file.

This tip is the complementary complementary "Popular Guide to Load Bitmap Files in the Java Application", which shows the process of loading bitmap files in the Java application. This month I will provide a tutorial that explains how to save images in a 24-bit bitmap file, which also contains a piece of code to write image objects into the bitgraph file.

If you work in the Microsoft Windows environment, the function of creating bitmap files will provide you with many convenience. For example, in my last project, I have to connect Java with Microsoft Access. The Java program allows the user to draw on the screen. This picture is then printed into the Microsoft Access report. Since Java does not support OLE, my only choice is to create a bitmap file for this figure and inform the Microsoft Access report where to find this bitmap file. If you write an application that sends an image to the clipboard, this tip may be useful to you - especially when you pass this information to another application.

Bitmap file format

The bitmap file format supports 4-bit RLE (stroke length coding) and 8-bit and 24-bit encoding. Because we only deal with 24-bit format, let's take a look at the structure of the file.

The bitmap file is divided into three parts. I have listed them below.

Part 1: headers of bitmap files

Headers contain type size information and layout information of bitmap files. The structure is as follows (taken from the C language structure):

Typedef struct tagbitmapfileHeader {uint bftype; dword bfsize; uint bfreserved1; uint bfreserved2; dword bfofbits;} BitmapfileHeader;

Here is an instructions for code elements in this list:

BFTYPE: Specifies the file type whose value is always BM.

BFSIZE: Specifies the size of the entire file (in bytes).

BFRESERVED1: Reserved - must be 0.

BFRESERVED2: Reserved - must be 0.

BFOFFBITS: Specifies the byte offset from BitmapFileHeader to the image header.

Now you have understood the use of bitmap headers to identify bitmap files. Each program of reading a bitmap file uses a bitmap header to perform file verification.

Part 2: Bitmap information header

The subsequent header is referred to as the information header, which contains the properties of the image itself.

Here's how to specify the size and color format of the Windows 3.0 (or higher) device stand-alone bitmap (DIB):

typedef struct tagBITMAPINFOHEADER {DWORD biSize; LONG biWidth; LONG biHeight; WORD biPlanes; WORD biBitCount; DWORD biCompression; DWORD biSizeImage; LONG biXPelsPerMeter; LONG biYPelsPerMeter; DWORD biClrUsed; DWORD biClrImportant;} BITMAPINFOHEADER;

Each element of the above code list is as follows:

Bisize: Specifies the number of bytes required for the BitmapInfoHeader structure. BiWidth: Specify the width of the bit map (in pixel).

Biheight: Specifies the height of the bitmap (in pixel).

BIPLANES: Specifies the number of parties for the target device. The value of this member variable must be 1.

BIBITCOUNT: Specifies the number of bits of each pixel. Its value must be 1,4, 8 or 24.

Bicompression: Specifies the compression type of the compressed bitmap. In the 24-bit format, the variable is set to 0.

BisizeImage: Specifies the size of the image (in bytes). If the format of the bitmap is BI_RGB, set this member variable to 0 is effective.

Bixpelspermeter: Specify the horizontal resolution of the target device (in "pixel / m"). The application can use this value to select a bitmap from a resource group that is most consistent with the current device feature.

Biypelspermeter: Specifies the vertical resolution of the target device for a bitmap (in "pixel / meter").

BICLRUSED: Indicates the color index number in the color table used in the location map. If BIBITCOUNT is set to 24, biclrused specifies a reference color table to optimize Windows palette performance.

BICLRIMPORTANT: Specifies the number of color indexes that have important impact on the display of bitmaps. If this value is 0, all colors is important.

All information needed to create images now has now defined.

Part 3: Image

In the 24-bit format, each pixel in the image is represented by a three-byte RGB sequence stored as a BRG. Each scan line is complemented to 4 digits. In order to make this process slightly more complicated, the image is stored on the bottom, that is, the first scan line is the last scanning line in the image. The following figure shows the header (BitmapHeader) and (BitMapInfoHead) and some images. Each part is separated by the vertical line:

0000000000 4D42 B536 0002 0000 0000 0036 0000 | 00280000000020 0000 0107 0000 00E0 0000 0001 0018 00000000000040 0000 B500 0002 0EC4 0000 0EC4 0000 00000000000060 0000 0000 0000 | FFFF FFFF FFFF FFFF FFFF0000000100 FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF *

Now, we start visiting the code

Now we already know the structure of the 24-bit bitmap file. Below you look forward to the long-awaited content: used to write the image object to the code of the bitmap file. Import java.awt. *; import java.io. *; import java.awt.image. *;

Public class bmpfile extends component {

File: // - Private constant private final static int bitmapfileHeader_size = 14; private final static int bitmapinfoHeader_size = 40;

File: // --- Private variable declaration

File: // --- bitmap file header private bote bitmapfileHeader [] = new byte [14]; private bote bftype [] = {'b', 'm'}; private int bfSize = 0; private int bfReserved1 = 0; private int bfReserved2 = 0; private int bfOffBits = BITMAPFILEHEADER_SIZE BITMAPINFOHEADER_SIZE; file: // --- bitmap information header 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 biCompression = 0; private int biSizeImage = 0x030000; private int biXPelsPerMeter = 0x0; private int biYPelsPerMeter = 0x0; private int biClrUsed = 0; Private int biclrimportant = 0;

File: // - Bitmap Original Data Private Int Bitmap [];

File: // --- Document part private fileoutputstream fo;

File: // - By default constructor public bmpfile () {

}

Public Void Savebitmap (String Parfilename, Image Parmage, INTPARWIDTH, INT PARHEIGHT) {

Try {fo = new fileoutputstream (Parfilename); Save (Parimage, Parwidth, Parheight); fo.close ();} catch (exception saveex) {saveex.printStackTrace ();

}

/ ** saveMethod is the main method of the process. This method * will call the ConvertImage method to convert the memory image to * byte arrays; WriteBitMapFileHeader method creation and write * bitmap file header; WriteBitMapInfoHeader creation * Information header; WriteBitmap is written to the image. ** / Private Void Save (Image Parimage, Int Parwidth, Int Parheight) {

Try {ConvertImage (Parimage, Parwidth, Parheight); WriteBitmapFileHeader (); WriteBitMapInfoHeader (); WriteBitmap ();} catch (exception saveex) {saveex.printStackTrace ();}}

/ ** CONVERTIMAGE converts memory images to a bitmap format (BRG). * It also calculates some information used by the bitmap information header. ** / Private Boolean ConvertImage (Image Parimage, Int Parwidth, Int Parheight) {

INT PAD; Bitmap = New Int 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 converts the image returned by the pixel capture to * required format. Keep in mind: Scanning line is in the bitmap file in reverse storage! ** Each scan must make up to 4 bytes. * / 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) // <==== Error correction PAD = 0; // <=== = Error correction rowcount = 1; padcount = 0; rowindex = size - biwidth; lastrowindex = rowindex;

Try {for (j = 0; j > 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;} elserowcount ; rowIndex ;}

File: // - Update file size bfsize = padcount - pad; bisizeImage = padcount - pad;} catch (exception wb) {wb.printStackTrace ();}

}

/ ** WriteBitMapFileHeader writes the bitmap file header into the file. ** / private void writebitmapfileheader () {

Try {fo.write; fo.write (IntedWord (INTTOWORD (INTTOWORD (BFRESERVED2)); fo.write (Intertodword (bfoffbits));} Catch (Exception WBFH) {wbfh.printStackTrace ();

}

/ *** WriteBitMapInfoHeader writes the bitmap information header * into the file. ** /

Private void writebitmapinfoheader () {

Try {fo.write; fo.Write (INTTODWORD (Biheight)); fo.write (INTTOT (INTTOTCOT (Bibitcount) ); fo.write (intToDWord (biCompression)); fo.write (intToDWord (biSizeImage)); fo.write (intToDWord (biXPelsPerMeter)); fo.write (intToDWord (biYPelsPerMeter)); fo.write (intToDWord (biClrUsed) ); fo.stodword (biclrimportant);} catch (exception wbih) {wbih.printstackTrace ();}

}

/ *** INTTOWORD converts the integer to a single word, return value * stored in a two-byartometer 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 integers to double words, return values ​​* 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);

}

}

summary

This is all the work you have to do. I am sure that you will find that this class is useful, because to JDK 1.1.6, Java does not support saving images in any common format. JDK 1.2 will support creating a JPEG image, but does not support creation bitmaps. So this class will still fill the gap in JDK1.2.

转载请注明原文地址:https://www.9cbs.com/read-4498.html

New Post(0)