📄 ch7.htm
字号:
private void extract8BitData( DataInputStream is )<BR> throws IOException<BR>{<BR> int index;<BR><BR> if ( biCompression == 0 )<BR> {<BR> int padding = 0;<BR> int overage = biWidth % 4;<BR> if ( overage != 0 )<BR> padding = 4 - overage;<BR> pix = new int[biHeight * biWidth];<BR> for ( int y = biHeight - 1; y >=0; y- )<BR> {<BR> index = y * biWidth;<BR> for ( int x = 0; x < biWidth; x++ )<BR> {<BR> pix[index++] = is.readUnsignedByte();<BR> }<BR> if ( padding != 0 ) is.skipBytes(padding);<BR> }<BR> }<BR> else<BR> {<BR> }<BR>}</TT></BLOCKQUOTE><P>Storage for 4 bits per pixel is similar to 8 bits per pixel, exceptthe data is stored two per byte. The next code block extracts4 bits per pixel data:<BLOCKQUOTE><TT>private void extract4BitData( DataInputStreamis )<BR> throws IOException<BR>{<BR> int index, temp = 0;<BR><BR> if ( biCompression == 0 )<BR> {<BR> int padding =0;<BR> int overage = ((biWidth + 1)/ 2) % 4;<BR> if ( overage !=0 )<BR> padding = 4 - overage;<BR> pix = new int[biHeight* biWidth];<BR> for ( int y = biHeight - 1; y >= 0; y-- )<BR> {<BR> index = y * biWidth;<BR> for ( int x = 0; x < biWidth;x++ )<BR> {<BR> //if on an even byte, read new 8 bit quantity<BR> // use low nibble of previous read forodd bytes<BR> if( (x % 2) == 0 )<BR> {<BR> temp = is.readUnsignedByte();<BR> pix[index++] =temp >> 4;<BR> }<BR> else<BR> pix[index++] =temp & 0x0f;<BR> }<BR> if ( padding != 0 ) is.skipBytes(padding);<BR> }<BR> }<BR> else<BR> {<BR> throw new IOException("Compressed images notsupported");<BR> }<BR>}</TT></BLOCKQUOTE><P>The real complication occurs when figuring the padding bytes.If the rows have an odd number of columns, then the last pixelwill take up an entire byte. To accommodate this, the width isbumped up by one before it is divided by two. This will forceodd-numbered columns to yield the correct number of bytes; even-numberedcolumns are unaffected (see the following code lines for an example):<BLOCKQUOTE><TT>11 columns: 11 / 2 = 5 [incorrect], (11+ 1) / 2 = 6 [correct]<BR>12 columns: 12 / 2 = 6 [correct], (12 + 1) /2 = 6 [correct]</TT></BLOCKQUOTE><P>Listing 7.1 displays the entire BmpImage class. At the bottomof the listing, you will see a static main function; it was addedto allow testing of the class. This function allows the classto be invoked from the command line as follows:<BLOCKQUOTE><TT>java BmpImage Forest.bmp</TT></BLOCKQUOTE><P>Although the image won't be rendered, the entire image will beprocessed, and all the header contents will be displayed to thescreen. In addition, any exceptions thrown during image extractionwill be displayed.<HR><BLOCKQUOTE><B>Listing 7.1. The BMP display class.<BR></B></BLOCKQUOTE><BLOCKQUOTE><TT>import java.io.*;<BR>import java.net.*;<BR>import java.awt.*;<BR>import java.awt.image.*;<BR><BR>public class BmpImage<BR>{<BR> String bfName;<BR> boolean imageProcessed;<BR> boolean windowsStyle;<BR> ColorModel colorModel = null;<BR> int pix[];<BR><BR> byte bfType[];<BR> int bfSize;<BR> int bfOffset;<BR> int biSize;<BR> int biWidth;<BR> int biHeight;<BR> int biPlanes;<BR> int biBitCount;<BR> int biCompression;<BR> int biSizeImage;<BR> int biXPelsPerMeter;<BR> int biYPelsPerMeter;<BR> int biClrUsed;<BR> int biClrImportant;<BR><BR> public BmpImage(String name)<BR> {<BR> bfName = name;<BR> bfType = new byte[2];<BR> imageProcessed= false;<BR> }<BR><BR> /**<BR> * A private method for extracting littleendian<BR> * quantities from a input stream.<BR> * @param is contains the input stream<BR> * @param len is the number of bytes inthe quantity<BR> * @returns the result as an integer<BR> */<BR> private int pullVal(DataInputStream is,int len)<BR> throws IOException<BR> {<BR> int value = 0;<BR> int temp = 0;<BR><BR> for ( int x =0; x < len; x++ )<BR> {<BR> temp= is.readUnsignedByte();<BR> value+= (temp << (x * 8));<BR> }<BR> return value;<BR> }<BR><BR> /**<BR> * A private method for extracting thefile header<BR> * portion of a BMP file.<BR> * @param is contains the input stream<BR> */<BR> private void extractFileHeader(DataInputStreamis)<BR> throws IOException,AWTException<BR> {<BR> is.read(bfType);<BR> if ( bfType[0]!= 'B' || bfType[1] != 'M' )<BR> thrownew AWTException("Not BMP format");<BR> bfSize = pullVal(is,4);<BR> is.skipBytes(4);<BR> bfOffset = pullVal(is,4);<BR> }<BR><BR> /**<BR> * A private method for extracting thecolor table from<BR> * a BMP type file.<BR> * @param is contains the input stream<BR> * @param numColors contains the biClrUsed(for Windows) or zero<BR> */<BR> private void extractColorMap(DataInputStreamis, int numColors)<BR> throws IOException,AWTException<BR> {<BR> byte blues[],reds[], greens[];<BR><BR> // if passed countis zero, then determine the<BR> // number of entriesfrom bits per pixel.<BR> if ( numColors== 0 )<BR> {<BR> switch( biBitCount )<BR> {<BR> case1: numColors = 2; break;<BR> case4: numColors = 16; break;<BR> case8: numColors = 256; break;<BR> case24: numColors = 0; break;<BR> default:numColors = -1; break;<BR> }<BR> }<BR> if ( numColors== -1 )<BR> thrownew AWTException("Invalid bits per pixel: " + biBitCount);<BR> else if ( numColors== 0 )<BR> colorModel= new DirectColorModel(24, 255 * 3, 255 * 2, 255);<BR> else<BR> {<BR> reds= new byte[numColors];<BR> blues= new byte[numColors];<BR> greens= new byte[numColors];<BR> for( int x = 0; x < numColors; x++ )<BR> {<BR> blues[x]= is.readByte();<BR> greens[x]= is.readByte();<BR> reds[x]= is.readByte();<BR> if( windowsStyle )<BR> is.skipBytes(1);<BR> }<BR> colorModel= new IndexColorModel( biBitCount, numColors,<BR> reds, greens, blues );<BR> }<BR> }<BR><BR> /**<BR> * A private method for extracting anOS/2 style<BR> * bitmap header.<BR> * @param is contains the input stream<BR> */<BR> private void extractOS2Style(DataInputStreamis)<BR> throws IOException,AWTException<BR> {<BR> windowsStyle =false;<BR> biWidth = pullVal(is,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -