Java reads BMP format pictures (source code, transfer)

zhaozj2021-02-16  130

Basic Objective

A windows BMP file is a common image format that Java does not handle. While BMP images are used only on windows machines, they are reasonably common. Reading these shows how to read complex structures in Java and

How to alter the byte order from the big endian order sale by java to the little endian order used by the windows and the intel processor.

-------------------------------------------------- --------

//

// this code WAS Taken and clean version

// javaworld tips and tricks column

//

Import

Java.awt.image;

Import

Java.awt.toolkit;

Import

Java.awt.image.MemoryImagesource;

Import

Java.io.fileinputstream;

Import

Java.io.ioException;

Import

Javax.swing.imageicon;

Import

Javax.swing.jframe;

Import

Javax.swing.jlabel;

Import

Javax.swing.jscrollpane;

//

// Really Just a Collection of Methods To Read A BMP File

//

public

Class Bmployader

{

// build an int from a byte array - converest Little to Big Endian

public

Static

Int constructint

Byte [] in,

INT offset {

INT RET =

Int in [Offset

3] &

0xFF);

Ret = (RET <<

8) |

Int in [Offset

2] &

0xFF);

Ret = (RET <<

8) |

Int in [Offset

1] &

0xFF);

Ret = (RET <<

8) |

Int in [Offset

0] &

0xFF);

Return (RET);

}

// build an int from a byte array - converest Little to Big Endian

// set high order bytes to 0xfff

public

Static

Int constructint3 (

Byte [] in,

INT offset {

int RET =

0xFF;

Ret = (RET <<

8) |

Int in [Offset

2] &

0xFF);

Ret = (RET <<

8) |

Int in [Offset

1] &

0xFF);

Ret = (RET <<

8) |

Int in [Offset

0] &

0xFF);

Return (RET);

}

// build an int from a byte array - conve port Little to Big Endianpublic

Static

Long Constructionlong

Byte [] in,

INT offset {

Long Ret = (("

Long) in [Offset

7] &

0xFF);

RET | = (RET <<

8) |

Long) in [Offset

6] &

0xFF);

RET | = (RET <<

8) |

Long) in [Offset

5] &

0xFF);

RET | = (RET <<

8) |

Long) in [Offset

4] &

0xFF);

RET | = (RET <<

8) |

Long) in [Offset

3] &

0xFF);

RET | = (RET <<

8) |

Long) in [Offset

2] &

0xFF);

RET | = (RET <<

8) |

Long) in [Offset

1] &

0xFF);

RET | = (RET <<

8) |

Long) in [Offset

0] &

0xFF);

Return (RET);

}

// build an double from a byte array - conve big little to big end

public

Static

Double constructdouble

Byte [] in,

INT offset {

Long Ret = Constructlong (in, offset);

Return (Double.longBitStodouble (RET));

}

// build an short from a byte array - Convert Little to Big Endian

public

Static

Short ConstructionShort

Byte [] in,

INT offset {

Short Ret =

SHORT)

Short) in [Offset

1] &

0xFF);

Ret =

Short) ((ret <<

8) |

SHORT)

Short) in [Offset

0] &

0xFF));

Return (RET);

}

// INTERNAL CLASS REPRESENTING A Bitmap HEADER STRUCTURE

// with code to read it from a file

Static

Class Bitmapheader {

public

Int nsize;

public

INT NBISIZE;

public

Int nwidth;

public

Int nHeiGHT;

public

Int nplanes;

public

Int nbitcount;

public

Int ncompression;

public

Int nsizeimage;

public

Int nxpm;

public

INT NYPM;

public

Int nclrused;

public

Int nclrimp;

// read in the bitmap header

public

Void Read

FileInputStream FS)

ThrowsioException

{

Final

Int bflen =

14;

// 14 Byte BitmapfileHeader

Byte bf [] =

New

BYTE [BFLEN];

fs.read (bf,

0, bflen);

Final

INT bilen =

40;

// 40-byte bitmapinfoheader

BYTE BI [] =

New

BYTE [BILEN];

fs.read (bi,

0, Bilen;

// Interperet Data. Nsize = constructint (BF,

2);

// system.out.println ("File Type IS:" (Char) BF [0] (CHAR) BF [1]);

// system.out.println ("SIZE OF FILE IS: NSize);

Nbisize = constructint (Bi,

2);

// system.out.println ("Size of BitmapInfoHeader IS:" Nbisize);

NWIDTH = Constructint (Bi,

4);

// system.out.println ("width is:" nwidth);

NHEIGHT = ConstructInt (Bi,

8);

// system.out.println ("Height IS:" NHEIGHT);

Nplanes = ConstructShort (Bi,

12);

// ((int) Bi [13] & 0xff) << 8) |

// (int) Bi [12] & 0xff;

// system.out.println ("Planes IS:" NPLANES);

Nbitcount = ConstructionShort (Bi,

14);

// ((int) Bi [15] & 0xff) << 8) |

// (int) BI [14] & 0xff;

// system.out.println ("Bitcount IS: NbitCount);

// Look for Non-Zero Values ​​To Indicate Compression Ncompression = ConstructInt (Bi,

16);

// system.out.println ("Compression IS: NCompRESSION);

nsizeImage = constructint (Bi,

20);

// system.out.println ("SizeImage is:" nsizeImage);

NXPM = Constructint (Bi,

twenty four);

// System.out.println ("X-Pixels Per meter is:" NXPM);

NYPM = Constructint (BI,

28);

// system.out.println ("Y-Pixels Per meter is:" NYPM);

nclrused = constructint (Bi,

32);

// system.out.println ("Colors Used Are: NCLRUSED);

Nclrimp = constructint (BI,

36);

// system.out.println ("Colors Important Are: NClrim);

}

}

public

Static

Image read

FileInputStream FS)

{

Try {

BitmapHeader BH =

New bitmapheader ();

Bh.read (fs);

IF (bh.nbitcount ==

twenty four)

Return (READMAP24 (FS, BH));

IF (bh.nbitcount ==

32)

Return (READMAP32 (FS, BH));

IF (bh.nbitcount ==

8)

Return (READMAP8 (FS, BH));

fs.close ();

}

Catch (

IOEXCEPTION E) {

// system.out.println ("Caught Exception in LoadBitMap!");

Return

NULL);

}

/ ** * * Readmap24 Internal routine to read the bytes in a 24 bit bitmap * * * * arguments: * * fs - file stream * * BH - Header struct * * returns: * * Image Object, Be Sure to Check for Image) NULL !!!! * * * * /

protected

Static

Image readmap32

FileInputStream Fs, BitmapHeader BH)

Throws

IOEXCEPTION

{

Image image;

// no Palatte Data for 24-bit Format But Scan Lines Are

// Padded Out to Even 4-byte boundaries.

INT xwidth = Bh.nsizeiMage / Bh.NHEIGHT;

Int nData [] =

New

int [BH.NHEIGHT * BH.NWIDTH];

Byte brgb [] =

New

Byte [Bh.NWIDTH *

4 * Bh.nHeight];

fs.read (brgb,

0, BH.NWIDTH *

4 * BH.NHEIGHT);

INT NINDEX =

0;

FOR

INT j =

0; j

{

FOR

INT i =

0; i

{

NData [Bh.NWIDTH * (BH.NHEIGHT - J -

1) i] = constructint3 (

BRGB, NINDEX);

NINDEX =

4;

}

}

Image = Toolkit.getDefaultToolkit (). CreateImage

(

New

MemoryImagesource (Bh.NWIDTH, BH.NHEIGHT,

NDATA,

0, BH.NWIDTH));

fs.close ();

Return (Image);

}

/ ** * * Readmap24 Internal routine to read the bytes in a 24 bit bitmap * * * * arguments: * * fs - file stream * * BH - Header struct * * returns: * * Image Object, Be Sure to Check for Image) NULL !!!! * * * * / protected

Static

Image readmap24 (

FileInputStream Fs, BitmapHeader BH)

Throws

IOEXCEPTION

{

Image image;

// no Palatte Data for 24-bit Format But Scan Lines Are

// Padded Out to Even 4-byte boundaries.

INT NPAD = (Bh.nsizeImage / Bh.NHEIGHT) - BH.NWIDTH *

3;

Int nData [] =

New

int [BH.NHEIGHT * BH.NWIDTH];

Byte brgb [] =

New

Byte [(Bh.NWIDTH NPAD) *

3 * Bh.nHeight];

fs.read (brgb,

0, (BH.NWIDTH NPAD) *

3 * bh.nheight);

INT NINDEX =

0;

FOR

INT j =

0; j

{

FOR

INT i =

0; i

{

NData [Bh.NWIDTH * (BH.NHEIGHT - J -

1) i] = constructint3 (

BRGB, NINDEX);

NINDEX =

3;

}

NINDEX = NPAD;

}

Image = Toolkit.getDefaultToolkit (). CreateImage

(

New

MemoryImagesource (Bh.NWIDTH, BH.NHEIGHT,

NDATA,

0, BH.NWIDTH));

fs.close ();

Return (Image);

}

/ ** * * readmap8 Internal routine to read the bytes in a 8 bitmap * * * * arguments: * * fs - file stream * * BH - Header struct * * returns: * * Image Object, Be Sure to Check for Image) NULL !!!! * * * * /

protected

Static

Image ketmap8

FileInputStream Fs, BitmapHeader BH)

Throws

IOEXCEPTION

{

Image image;

// Have to Determine The Number of Colors, The Clrsused

// Parameter Is Dominant if it is greater tour Zero. IF

// Zero, Calculate Colors Based on BitsPixel.Int nnumcolors =

0;

IF (Bh.NCLRUSED>

0)

{

Nnumcolors = BH.NCLRUSED;

}

Else

{

Nnumcolors =

1 &

0xFF) << Bh.nbitcount;

}

// system.out.println ("The Number of Colors Is" Nnumcolors);

// Some Bitmaps do not home the sizeimage field calculate

// Ferret Out these Cases and fix 'em.

IF (Bh.nsizeImage ==

0)

{

Bh.nsizeImage = (((Bh.nWidth * Bh.nbitcount)

31) & ~

31) >>

3);

Bh.nsizeImage * = BH.NHEIGHT;

// system.out.println ("NSIZEIMAGE (Backup) is" nsizeImage);

}

// read The Palatte Colors.

Int npalette [] =

New

Int [nnumcolors];

Byte bpalette [] =

New

Byte [nnumcolors *

4];

fs.read (bPalette,

0, nnumcolors *

4);

INT NINDEX8 =

0;

FOR

INT n =

0; n

{

NPALETTE [N] = ConstructInt3 (BPALETTE, NINDEX8);

NINDEX8 =

4;

}

// read the image data (actual component INTO THE PALETTE)

// Scan Lines Are Still Padded Out To Even 4-Byte

// boundaries.

INT NPAD8 = (Bh.nsizeImage / Bh.NHEIGHT) - BH.NWIDTH;

// system.out.println ("NPAD IS:" NPAD8);

Int nData8 [] =

New

Int [Bh.nWidth * Bh.nHeight];

Byte bdata [] =

New

Byte [(Bh.nWidth NPAD8) * BH.NHEIGHT];

Fs.read (BData,

0, (Bh.nWidth NPAD8) * BH.NHEIGHT);

NINDEX8 =

0;

FOR

INT J8 =

0; J8

{

FOR

INT i8 =

0; I8

{

NDATA8 [BH.NWIDTH * (BH.NHEIGHT - J8 - J8 -

1) i8] =

NPALETTE [((

Int) BData [Nindex8] &

0xFF)];

NINDEX8 ;

}

NINDEX8 = NPAD8;

}

Image = Toolkit.getDefaultToolkit (). CreateImage

(

New

MemoryImagesource (Bh.NWIDTH, BH.NHEIGHT,

NDATA8,

0, BH.NWIDTH));

Return (Image);

}

/ ** * * load method - See read for details * * * * arguments: * * sdir and sfile all the result of the filedialog () * getdirectory () and getfile () methods. * * * * Returns: * * Image Object, Be Sure To Check for (Image) NULL !!!! * * * * /

public

Static

Image load

String SDIR,

String sfile) {

Return (LOAD (SDIR SFILE));

}

/ ** * * load method - See read for details * * * * arguments: * * sdir - full path name * * * * returns: * * Image Object, be sure to check for (image) null !!!! * * * * /

public

Static

Image load

String SDIR)

{

Try

{

FileInputStream Fs =

New

FileInputStream (SDIR);

Return (READ (FS));

}

Catch (

IOEXCEPTION EX) {

Return

NULL);

}

}

public

Static

Void main

String [] ARGS)

Throws

IOEXCEPTION

{

IF (args.length ==

0) {

System.out.println (

"USAGE> JAVA BMPLOADER ImageFile.BMP");

SYSTEM.EXIT (

0);

}

FileInputStream in =

New

FileInputStream (Args [

0]);

Image theimage = = read (in);

JFrame theframe =

New

JFrame (Args [

0]);

Jlabel thelabel =

New

Jlabel

New

Imageicon (TheImage);

Theframe.getContentPane (). Add (

New

Jscrollpane (TheLabel);

Theframe.setsize

300,

300);

Theframe.setvisible

True);

}

// end class bmploader}

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

New Post(0)