?? bmpreader.java
字號:
package javaexplorer.io.reader;import java.awt.*;import java.awt.image.*;import java.io.*;// This class provides a public static method that takes an InputStream// to a Windows .BMP file and converts it into an ImageProducer via// a MemoryImageSource.// You can fetch a .BMP through a URL with the following code:// URL url = new URL( <wherever your URL is> )// Image img = createImage(BMPReader.getBMPImage(url.openStream()));public class BMPReader extends Object { // Constants indicating how the data is stored public static final int BI_RGB = 0; public static final int BI_RLE8 = 1; public static final int BI_RLE4 = 2; public static int is; public static Image getImage(File file) { Image img = null; try { ImageProducer ip = BMPReader.getBMPImage(new FileInputStream(file)); img = Toolkit.getDefaultToolkit().createImage(ip); } catch (Exception e) { javaexplorer.util.Log.addError(e); } return img; } public static Image getImage(byte[] buf) { Image img = null; try { java.io.ByteArrayInputStream bais = new java.io.ByteArrayInputStream(buf); ImageProducer ip = BMPReader.getBMPImage(bais); img = Toolkit.getDefaultToolkit().createImage(ip); } catch (Exception e) { javaexplorer.util.Log.addError(e); } return img; } public static ImageProducer getBMPImage(InputStream stream) throws IOException { // The DataInputStream allows you to read in 16 and 32 bit numbers DataInputStream in = new DataInputStream(stream); // Verify that the header starts with 'BM' if (in.read() != 'B') { throw new IOException("Not a .BMP file"); } if (in.read() != 'M') { throw new IOException("Not a .BMP file"); } // Get the total file size int fileSize = intelInt(in.readInt()); // Skip the 2 16-bit reserved words in.readUnsignedShort(); in.readUnsignedShort(); int bitmapOffset = intelInt(in.readInt()); int bitmapInfoSize = intelInt(in.readInt()); int width = intelInt(in.readInt()); int height = intelInt(in.readInt()); // Skip the 16-bit bitplane size in.readUnsignedShort(); int bitCount = intelShort(in.readUnsignedShort()); int compressionType = intelInt(in.readInt()); int imageSize = intelInt(in.readInt()); is = imageSize; // Skip pixels per meter in.readInt(); in.readInt(); int colorsUsed = intelInt(in.readInt()); int colorsImportant = intelInt(in.readInt()); if (colorsUsed == 0) { colorsUsed = 1 << bitCount; } // Create space for the pixels int[] pixels = new int[width * height]; if (bitCount != 24) { int[] colorTable = new int[colorsUsed]; // Read the bitmap's color table for (int i = 0; i < colorsUsed; i++) { //System.out.println(i + " "); colorTable[i] = (intelInt(in.readInt()) & 0xffffff) + 0xff000000; } // Read the pixels from the stream based on the compression type if (compressionType == BI_RGB) { readRGB(width, height, colorTable, bitCount, pixels, in); } else if (compressionType == BI_RLE8) { readRLE(width, height, colorTable, bitCount, pixels, in, imageSize, 8); } else if (compressionType == BI_RLE4) { readRLE(width, height, colorTable, bitCount, pixels, in, imageSize, 4); } } else { readRGB24(width, height, pixels, in); } // Create a memory image source from the pixels return new MemoryImageSource(width, height, pixels, 0, width); } // Reads in pixels in 24-bit format. There is no color table, and the // pixels are stored in 3-byte pairs. Oddly, all windows bitmaps are // stored upside-down - the bottom line is stored first. protected static void readRGB24(int width, int height, int[] pixels, DataInputStream in) throws IOException { // Start storing at the bottom of the array for (int h = height - 1; h >= 0; h--) { int pos = h * width; for (int w = 0; w < width; w++) { // Read in the red, green, and blue components int red = in.readUnsignedByte(); int green = in.readUnsignedByte(); int blue = in.readUnsignedByte(); // Turn the red, green, and blue values into an RGB color with // an alpha value of 255 (fully opaque) //pixels[pos++] = 0xff000000 + (red << 16) + (green << 8) + blue; pixels[pos++] = 0xff000000 + red + (green << 8) + (blue << 16); } long off = (is / height) - (width * 3); for (int j = 0; j < off; j++) in.readUnsignedByte(); } } // readRGB reads in pixels values that are stored uncompressed. // The bits represent indices into the color table. protected static void readRGB(int width, int height, int[] colorTable, int bitCount, int[] pixels, DataInputStream in) throws IOException { // How many pixels can be stored in a byte? int pixelsPerByte = 8 / bitCount; // A bit mask containing the number of bits in a pixel int bitMask = (1 << bitCount) - 1; // The shift values that will move each pixel to the far right int[] bitShifts = new int[pixelsPerByte]; for (int i = 0; i < pixelsPerByte; i++) { bitShifts[i] = 8 - ((i + 1) * bitCount); } int whichBit = 0; // Read in the first byte int currByte = in.read(); long off = (is - ((height * width) / pixelsPerByte)) / height; // System.out.println("is: " + is + " bitCount: " + bitCount + " off: " + off); if ((off < 0) || (is == 0)) { if ((bitCount == 8) && (height != width)) { off = 3; } } // Start at the bottom of the pixel array and work up for (int h = height - 1; h >= 0; h--) { int pos = h * width; for (int w = 0; w < width; w++) { // Get the next pixel from the current byte try { pixels[pos] = colorTable[(currByte >> bitShifts[whichBit]) & bitMask]; } catch (ArrayIndexOutOfBoundsException ae) { // System.out.println("Array out of bounds, pos = " + pos); break; } pos++; whichBit++; // If the current bit position is past the number of pixels in // a byte, we advance to the next byte if (whichBit >= pixelsPerByte) { whichBit = 0; currByte = in.read(); } } // end for // System.out.println("height: " + height + " width: " + width + " is: " + is); try { for (int j = 0; j < off; j++) in.readUnsignedByte(); } catch (EOFException e) { /*System.out.println("Still something wrong");*/ } } // end for } // readRLE reads run-length encoded data in either RLE4 or RLE8 format. protected static void readRLE(int width, int height, int[] colorTable, int bitCount, int[] pixels, DataInputStream in, int imageSize, int pixelSize) throws IOException { int x = 0; int y = height - 1; // You already know how many bytes are in the image, so only go // through that many. for (int i = 0; i < imageSize; i++) { // RLE encoding is defined by two bytes int byte1 = in.read(); int byte2 = in.read(); i += 2; // If byte 0 == 0, this is an escape code if (byte1 == 0) { // If escaped, byte 2 == 0 means you are at end of line if (byte2 == 0) { x = 0; y--; // If escaped, byte 2 == 1 means end of bitmap } else if (byte2 == 1) { return; // if escaped, byte 2 == 2 adjusts the current x and y by // an offset stored in the next two words } else if (byte2 == 2) { int xoff = (char) intelShort(in.readUnsignedShort()); i += 2; int yoff = (char) intelShort(in.readUnsignedShort()); i += 2; x += xoff; y -= yoff; // If escaped, any other value for byte 2 is the number of bytes // that you should read as pixel values (these pixels are not // run-length encoded) } else { int whichBit = 0; // Read in the next byte int currByte = in.read(); i++; for (int j = 0; j < byte2; j++) { if (pixelSize == 4) { // The pixels are 4-bits, so half the time you shift the current byte // to the right as the pixel value if (whichBit == 0) { pixels[(y * width) + x] = colorTable[(currByte >> 4) & 0xf]; } else { // The rest of the time, you mask out the upper 4 bits, save the pixel // value, then read in the next byte pixels[(y * width) + x] = colorTable[currByte & 0xf]; currByte = in.read(); i++; } } else { pixels[(y * width) + x] = colorTable[currByte]; currByte = in.read(); i++; } x++; if (x >= width) { x = 0; y--; } } // The pixels must be word-aligned, so if you read an uneven number of // bytes, read and ignore a byte to get aligned again. if ((byte2 & 1) == 1) { in.read(); i++; } } // If the first byte was not 0, it is the number of pixels that // are encoded by byte 2 } else { for (int j = 0; j < byte1; j++) { if (pixelSize == 4) { // If j is odd, use the upper 4 bits if ((j & 1) == 0) { pixels[(y * width) + x] = colorTable[(byte2 >> 4) & 0xf]; } else { pixels[(y * width) + x + 1] = colorTable[byte2 & 0xf]; } } else { pixels[(y * width) + x + 1] = colorTable[byte2]; } x++; if (x >= width) { x = 0; y--; } } } } } // intelShort converts a 16-bit number stored in intel byte order into // the local host format protected static int intelShort(int i) { return ((i >> 8) & 0xff) + ((i << 8) & 0xff00); } // intelInt converts a 32-bit number stored in intel byte order into // the local host format protected static int intelInt(int i) { return ((i & 0xff) << 24) + ((i & 0xff00) << 8) + ((i & 0xff0000) >> 8) + ((i >> 24) & 0xff); }}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -