📄 pngencoderb.java
字号:
protected void writeHeader() { int startPos; startPos = bytePos = writeInt4( 13, bytePos ); bytePos = writeBytes( IHDR, bytePos ); width = image.getWidth( null ); height = image.getHeight( null ); bytePos = writeInt4( width, bytePos ); bytePos = writeInt4( height, bytePos ); bytePos = writeByte( 8, bytePos ); // bit depth if (bytesPerPixel != 1) { bytePos = writeByte( (encodeAlpha) ? 6 : 2, bytePos ); // direct model } else { bytePos = writeByte( 3, bytePos ); // indexed } bytePos = writeByte( 0, bytePos ); // compression method bytePos = writeByte( 0, bytePos ); // filter method bytePos = writeByte( 0, bytePos ); // no interlace crc.reset(); crc.update( pngBytes, startPos, bytePos-startPos ); crcValue = crc.getValue(); bytePos = writeInt4( (int) crcValue, bytePos ); } protected void writePalette( IndexColorModel icm ) { byte[] redPal = new byte[256]; byte[] greenPal = new byte[256]; byte[] bluePal = new byte[256]; byte[] allPal = new byte[768]; int i; icm.getReds( redPal ); icm.getGreens( greenPal ); icm.getBlues( bluePal ); for (i=0; i<256; i++) { allPal[i*3 ] = redPal[i]; allPal[i*3+1] = greenPal[i]; allPal[i*3+2] = bluePal[i]; } bytePos = writeInt4( 768, bytePos ); bytePos = writeBytes( PLTE, bytePos ); crc.reset(); crc.update( PLTE ); bytePos = writeBytes( allPal, bytePos ); crc.update( allPal ); crcValue = crc.getValue(); bytePos = writeInt4( (int) crcValue, bytePos ); } /** * Write the image data into the pngBytes array. * This will write one or more PNG "IDAT" chunks. In order * to conserve memory, this method grabs as many rows as will * fit into 32K bytes, or the whole image; whichever is less. * * * @return true if no errors; false if error grabbing pixels */ protected boolean writeImageData() { int rowsLeft = height; // number of rows remaining to write int startRow = 0; // starting row to process this time through int nRows; // how many rows to grab at a time byte[] scanLines; // the scan lines to be compressed int scanPos; // where we are in the scan lines int startPos; // where this line's actual pixels start (used for filtering) int readPos; // position from which source pixels are read byte[] compressedLines; // the resultant compressed lines int nCompressed; // how big is the compressed area? byte[] pixels; // storage area for byte-sized pixels int[] iPixels; // storage area for int-sized pixels short[] sPixels; // for Win 2000/ME ushort pixels final int type = image.getType(); // TYPE_INT_RGB = 1 // TYPE_INT_ARGB = 2 // TYPE_INT_ARGB_PRE = 3 // TYPE_INT_BGR = 4 // TYPE_3BYTE_BGR = 5 // TYPE_4BYTE_ABGR = 6 // TYPE_4BYTE_ABGR_PRE = 7 // TYPE_BYTE_GRAY = 10 // TYPE_BYTE_BINARY = 12 // TYPE_BYTE_INDEXED = 13 // TYPE_USHORT_GRAY = 11 // TYPE_USHORT_565_RGB = 8 // TYPE_USHORT_555_RGB = 9 // TYPE_CUSTOM = 0. Deflater scrunch = new Deflater( compressionLevel ); ByteArrayOutputStream outBytes = new ByteArrayOutputStream(1024); DeflaterOutputStream compBytes = new DeflaterOutputStream( outBytes, scrunch ); if (bytesPerPixel == 1) { writePalette( (IndexColorModel) image.getColorModel() ); } try { while (rowsLeft > 0) { nRows = Math.min( 32767 / (width*(bytesPerPixel+1)), rowsLeft ); nRows = Math.max( nRows, 1 ); /* * Create a data chunk. scanLines adds "nRows" for * the filter bytes. */ scanLines = new byte[width * nRows * bytesPerPixel + nRows]; if (filter == FILTER_SUB) { leftBytes = new byte[16]; } if (filter == FILTER_UP) { priorRow = new byte[width*bytesPerPixel]; } final Object data = wRaster.getDataElements( 0, startRow, width, nRows, null ); pixels = null; iPixels = null; sPixels = null; if (tType == DataBuffer.TYPE_BYTE) { pixels = (byte[]) data; } else if (tType == DataBuffer.TYPE_INT) { iPixels = (int[]) data; } else if (tType == DataBuffer.TYPE_USHORT) { sPixels = (short[]) data; } scanPos = 0; readPos = 0; startPos = 1; for (int i=0; i<width*nRows; i++) { if (i % width == 0) { scanLines[scanPos++] = (byte) filter; startPos = scanPos; } if (bytesPerPixel == 1) // assume TYPE_BYTE, indexed { scanLines[scanPos++] = pixels[readPos++]; } else if (tType == DataBuffer.TYPE_BYTE) { scanLines[scanPos++] = pixels[readPos++]; scanLines[scanPos++] = pixels[readPos++]; scanLines[scanPos++] = pixels[readPos++]; if (encodeAlpha) { scanLines[scanPos++] = pixels[readPos++]; } else { readPos++; } } else if (tType == DataBuffer.TYPE_USHORT) { short pxl = sPixels[readPos++]; if (type == BufferedImage.TYPE_USHORT_565_RGB) { scanLines[scanPos++] = (byte) ((pxl >> 8) & 0xf8); scanLines[scanPos++] = (byte) ((pxl >> 2) & 0xfc); } else { // assume USHORT_555_RGB scanLines[scanPos++] = (byte) ((pxl >> 7) & 0xf8); scanLines[scanPos++] = (byte) ((pxl >> 2) & 0xf8); } scanLines[scanPos++] = (byte) ((pxl << 3) & 0xf8); } else // assume tType INT and type RGB or ARGB { int pxl = iPixels[readPos++]; scanLines[scanPos++] = (byte) ((pxl >> 16) & 0xff); scanLines[scanPos++] = (byte) ((pxl >> 8) & 0xff); scanLines[scanPos++] = (byte) ((pxl ) & 0xff); if (encodeAlpha) { scanLines[scanPos++] = (byte) ((pxl >> 24) & 0xff); } } if ((i % width == width-1) && (filter != FILTER_NONE)) { if (filter == FILTER_SUB) { filterSub( scanLines, startPos, width ); } if (filter == FILTER_UP) { filterUp( scanLines, startPos, width ); } } } /* * Write these lines to the output area */ compBytes.write( scanLines, 0, scanPos ); startRow += nRows; rowsLeft -= nRows; } compBytes.close(); /* * Write the compressed bytes */ compressedLines = outBytes.toByteArray(); nCompressed = compressedLines.length; crc.reset(); bytePos = writeInt4( nCompressed, bytePos ); bytePos = writeBytes( IDAT, bytePos ); crc.update( IDAT ); bytePos = writeBytes( compressedLines, nCompressed, bytePos ); crc.update( compressedLines, 0, nCompressed ); crcValue = crc.getValue(); bytePos = writeInt4( (int) crcValue, bytePos ); scrunch.finish(); return true; } catch (IOException e) { System.err.println( e.toString()); return false; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -