📄 pngimagewriter.java
字号:
cs.writeInt(metadata.cHRM_whitePointY); cs.writeInt(metadata.cHRM_redX); cs.writeInt(metadata.cHRM_redY); cs.writeInt(metadata.cHRM_greenX); cs.writeInt(metadata.cHRM_greenY); cs.writeInt(metadata.cHRM_blueX); cs.writeInt(metadata.cHRM_blueY); cs.finish(); } } private void write_gAMA() throws IOException { if (metadata.gAMA_present) { ChunkStream cs = new ChunkStream(PNGImageReader.gAMA_TYPE, stream); cs.writeInt(metadata.gAMA_gamma); cs.finish(); } } private void write_iCCP() throws IOException { if (metadata.iCCP_present) { ChunkStream cs = new ChunkStream(PNGImageReader.iCCP_TYPE, stream); cs.writeBytes(metadata.iCCP_profileName); cs.writeByte(0); // null terminator cs.writeByte(metadata.iCCP_compressionMethod); cs.write(metadata.iCCP_compressedProfile); cs.finish(); } } private void write_sBIT() throws IOException { if (metadata.sBIT_present) { ChunkStream cs = new ChunkStream(PNGImageReader.sBIT_TYPE, stream); int colorType = metadata.IHDR_colorType; if (metadata.sBIT_colorType != colorType) { processWarningOccurred(0,"sBIT metadata has wrong color type.\n" +"The chunk will not be written."); return; } if (colorType == PNGImageReader.PNG_COLOR_GRAY || colorType == PNGImageReader.PNG_COLOR_GRAY_ALPHA) { cs.writeByte(metadata.sBIT_grayBits); } else if (colorType == PNGImageReader.PNG_COLOR_RGB || colorType == PNGImageReader.PNG_COLOR_PALETTE || colorType == PNGImageReader.PNG_COLOR_RGB_ALPHA) { cs.writeByte(metadata.sBIT_redBits); cs.writeByte(metadata.sBIT_greenBits); cs.writeByte(metadata.sBIT_blueBits); } if (colorType == PNGImageReader.PNG_COLOR_GRAY_ALPHA || colorType == PNGImageReader.PNG_COLOR_RGB_ALPHA) { cs.writeByte(metadata.sBIT_alphaBits); } cs.finish(); } } private void write_sRGB() throws IOException { if (metadata.sRGB_present) { ChunkStream cs = new ChunkStream(PNGImageReader.sRGB_TYPE, stream); cs.writeByte(metadata.sRGB_renderingIntent); cs.finish(); } } private void write_PLTE() throws IOException { if (metadata.PLTE_present) { if (metadata.IHDR_colorType == PNGImageReader.PNG_COLOR_GRAY || metadata.IHDR_colorType == PNGImageReader.PNG_COLOR_GRAY_ALPHA) { // PLTE cannot occur in a gray image processWarningOccurred(0,"A PLTE chunk may not appear in a gray or gray alpha image.\n" +"The chunk will not be written"); return; } ChunkStream cs = new ChunkStream(PNGImageReader.PLTE_TYPE, stream); int numEntries = metadata.PLTE_red.length; byte[] palette = new byte[numEntries*3]; int index = 0; for (int i = 0; i < numEntries; i++) { palette[index++] = metadata.PLTE_red[i]; palette[index++] = metadata.PLTE_green[i]; palette[index++] = metadata.PLTE_blue[i]; } cs.write(palette); cs.finish(); } } private void write_hIST() throws IOException, IIOException { if (metadata.hIST_present) { ChunkStream cs = new ChunkStream(PNGImageReader.hIST_TYPE, stream); if (!metadata.PLTE_present) { throw new IIOException("hIST chunk without PLTE chunk!"); } cs.writeChars(metadata.hIST_histogram, 0, metadata.hIST_histogram.length); cs.finish(); } } private void write_tRNS() throws IOException, IIOException { if (metadata.tRNS_present) { ChunkStream cs = new ChunkStream(PNGImageReader.tRNS_TYPE, stream); int colorType = metadata.IHDR_colorType; int chunkType = metadata.tRNS_colorType; // Special case: image is RGB and chunk is Gray // Promote chunk contents to RGB int chunkRed = metadata.tRNS_red; int chunkGreen = metadata.tRNS_green; int chunkBlue = metadata.tRNS_blue; if (colorType == PNGImageReader.PNG_COLOR_RGB && chunkType == PNGImageReader.PNG_COLOR_GRAY) { chunkType = colorType; chunkRed = chunkGreen = chunkBlue = metadata.tRNS_gray; } if (chunkType != colorType) { processWarningOccurred(0,"tRNS metadata has incompatible color type.\n" +"The chunk will not be written."); return; } if (colorType == PNGImageReader.PNG_COLOR_PALETTE) { if (!metadata.PLTE_present) { throw new IIOException("tRNS chunk without PLTE chunk!"); } cs.write(metadata.tRNS_alpha); } else if (colorType == PNGImageReader.PNG_COLOR_GRAY) { cs.writeShort(metadata.tRNS_gray); } else if (colorType == PNGImageReader.PNG_COLOR_RGB) { cs.writeShort(chunkRed); cs.writeShort(chunkGreen); cs.writeShort(chunkBlue); } else { throw new IIOException("tRNS chunk for color type 4 or 6!"); } cs.finish(); } } private void write_bKGD() throws IOException { if (metadata.bKGD_present) { ChunkStream cs = new ChunkStream(PNGImageReader.bKGD_TYPE, stream); int colorType = metadata.IHDR_colorType & 0x3; int chunkType = metadata.bKGD_colorType; // Special case: image is RGB(A) and chunk is Gray // Promote chunk contents to RGB int chunkRed = metadata.bKGD_red; int chunkGreen = metadata.bKGD_red; int chunkBlue = metadata.bKGD_red; if (colorType == PNGImageReader.PNG_COLOR_RGB && chunkType == PNGImageReader.PNG_COLOR_GRAY) { // Make a gray bKGD chunk look like RGB chunkType = colorType; chunkRed = chunkGreen = chunkBlue = metadata.bKGD_gray; } // Ignore status of alpha in colorType if (chunkType != colorType) { processWarningOccurred(0,"bKGD metadata has incompatible color type.\n" +"The chunk will not be written."); return; } if (colorType == PNGImageReader.PNG_COLOR_PALETTE) { cs.writeByte(metadata.bKGD_index); } else if (colorType == PNGImageReader.PNG_COLOR_GRAY || colorType == PNGImageReader.PNG_COLOR_GRAY_ALPHA) { cs.writeShort(metadata.bKGD_gray); } else { // colorType == PNGImageReader.PNG_COLOR_RGB || // colorType == PNGImageReader.PNG_COLOR_RGB_ALPHA cs.writeShort(chunkRed); cs.writeShort(chunkGreen); cs.writeShort(chunkBlue); } cs.finish(); } } private void write_pHYs() throws IOException { if (metadata.pHYs_present) { ChunkStream cs = new ChunkStream(PNGImageReader.pHYs_TYPE, stream); cs.writeInt(metadata.pHYs_pixelsPerUnitXAxis); cs.writeInt(metadata.pHYs_pixelsPerUnitYAxis); cs.writeByte(metadata.pHYs_unitSpecifier); cs.finish(); } } private void write_sPLT() throws IOException { if (metadata.sPLT_present) { ChunkStream cs = new ChunkStream(PNGImageReader.sPLT_TYPE, stream); cs.writeBytes(metadata.sPLT_paletteName); cs.writeByte(0); // null terminator cs.writeByte(metadata.sPLT_sampleDepth); int numEntries = metadata.sPLT_red.length; if (metadata.sPLT_sampleDepth == 8) { for (int i = 0; i < numEntries; i++) { cs.writeByte(metadata.sPLT_red[i]); cs.writeByte(metadata.sPLT_green[i]); cs.writeByte(metadata.sPLT_blue[i]); cs.writeByte(metadata.sPLT_alpha[i]); cs.writeShort(metadata.sPLT_frequency[i]); } } else { // sampleDepth == 16 for (int i = 0; i < numEntries; i++) { cs.writeShort(metadata.sPLT_red[i]); cs.writeShort(metadata.sPLT_green[i]); cs.writeShort(metadata.sPLT_blue[i]); cs.writeShort(metadata.sPLT_alpha[i]); cs.writeShort(metadata.sPLT_frequency[i]); } } cs.finish(); } } private void write_tIME() throws IOException { if (metadata.tIME_present) { ChunkStream cs = new ChunkStream(PNGImageReader.tIME_TYPE, stream); cs.writeShort(metadata.tIME_year); cs.writeByte(metadata.tIME_month); cs.writeByte(metadata.tIME_day); cs.writeByte(metadata.tIME_hour); cs.writeByte(metadata.tIME_minute); cs.writeByte(metadata.tIME_second); cs.finish(); } } private void write_tEXt() throws IOException { Iterator keywordIter = metadata.tEXt_keyword.iterator(); Iterator textIter = metadata.tEXt_text.iterator(); while (keywordIter.hasNext()) { ChunkStream cs = new ChunkStream(PNGImageReader.tEXt_TYPE, stream); String keyword = (String)keywordIter.next(); cs.writeBytes(keyword); cs.writeByte(0); String text = (String)textIter.next(); cs.writeBytes(text); cs.finish(); } } private byte[] deflate(String s) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); DeflaterOutputStream dos = new DeflaterOutputStream(baos); int len = s.length(); for (int i = 0; i < len; i++) { dos.write((int)s.charAt(i)); } dos.close(); return baos.toByteArray(); } private void write_iTXt() throws IOException { Iterator keywordIter = metadata.iTXt_keyword.iterator(); Iterator flagIter = metadata.iTXt_compressionFlag.iterator(); Iterator methodIter = metadata.iTXt_compressionMethod.iterator(); Iterator languageIter = metadata.iTXt_languageTag.iterator(); Iterator translatedKeywordIter = metadata.iTXt_translatedKeyword.iterator(); Iterator textIter = metadata.iTXt_text.iterator(); while (keywordIter.hasNext()) { ChunkStream cs = new ChunkStream(PNGImageReader.iTXt_TYPE, stream); String keyword = (String)keywordIter.next(); cs.writeBytes(keyword); cs.writeByte(0); int flag = ((Integer)flagIter.next()).intValue(); cs.writeByte(flag); int method = ((Integer)methodIter.next()).intValue(); cs.writeByte(method); String languageTag = (String)languageIter.next(); cs.writeBytes(languageTag); cs.writeByte(0); String translatedKeyword = (String)translatedKeywordIter.next(); cs.writeBytes(translatedKeyword); cs.writeByte(0); String text = (String)textIter.next(); if (flag == 1) { cs.write(deflate(text)); } else { cs.writeUTF(text); } cs.finish(); } } private void write_zTXt() throws IOException { Iterator keywordIter = metadata.zTXt_keyword.iterator(); Iterator methodIter = metadata.zTXt_compressionMethod.iterator(); Iterator textIter = metadata.zTXt_text.iterator(); while (keywordIter.hasNext()) { ChunkStream cs = new ChunkStream(PNGImageReader.zTXt_TYPE, stream); String keyword = (String)keywordIter.next(); cs.writeBytes(keyword); cs.writeByte(0); int compressionMethod = ((Integer)methodIter.next()).intValue(); cs.writeByte(compressionMethod); String text = (String)textIter.next(); cs.write(deflate(text)); cs.finish(); } } private void writeUnknownChunks() throws IOException { Iterator typeIter = metadata.unknownChunkType.iterator(); Iterator dataIter = metadata.unknownChunkData.iterator(); while (typeIter.hasNext() && dataIter.hasNext()) { String type = (String)typeIter.next(); ChunkStream cs = new ChunkStream(chunkType(type), stream); byte[] data = (byte[])dataIter.next(); cs.write(data); cs.finish(); } } private static int chunkType(String typeString) { char c0 = typeString.charAt(0); char c1 = typeString.charAt(1); char c2 = typeString.charAt(2); char c3 = typeString.charAt(3); int type = (c0 << 24) | (c1 << 16) | (c2 << 8) | c3; return type; } private void encodePass(ImageOutputStream os, RenderedImage image, int xOffset, int yOffset, int xSkip, int ySkip) throws IOException { int minX = sourceXOffset; int minY = sourceYOffset; int width = sourceWidth; int height = sourceHeight; // Adjust offsets and skips based on source subsampling factors xOffset *= periodX; xSkip *= periodX; yOffset *= periodY; ySkip *= periodY; // Early exit if no data for this pass int hpixels = (width - xOffset + xSkip - 1)/xSkip; int vpixels = (height - yOffset + ySkip - 1)/ySkip; if (hpixels == 0 || vpixels == 0) { return; } // Convert X offset and skip from pixels to samples xOffset *= numBands; xSkip *= numBands;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -