⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pngimagewriter.java

📁 Mobile 应用程序使用 Java Micro Edition (Java ME) 平台
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
        // Create row buffers        int samplesPerByte = 8/metadata.IHDR_bitDepth;        int numSamples = width*numBands;        int[] samples = new int[numSamples];        int bytesPerRow = hpixels*numBands;        if (metadata.IHDR_bitDepth < 8) {            bytesPerRow = (bytesPerRow + samplesPerByte - 1)/samplesPerByte;        } else if (metadata.IHDR_bitDepth == 16) {            bytesPerRow *= 2;        }        IndexColorModel icm_gray_alpha = null;        if (metadata.IHDR_colorType == PNGImageReader.PNG_COLOR_GRAY_ALPHA &&            image.getColorModel() instanceof IndexColorModel)        {            // reserve space for alpha samples            bytesPerRow *= 2;                        // will be used to calculate alpha value for the pixel            icm_gray_alpha = (IndexColorModel)image.getColorModel();        }         currRow = new byte[bytesPerRow + bpp];        prevRow = new byte[bytesPerRow + bpp];        filteredRows = new byte[5][bytesPerRow + bpp];	int bitDepth = metadata.IHDR_bitDepth;        for (int row = minY + yOffset; row < minY + height; row += ySkip) {            Rectangle rect = new Rectangle(minX, row, width, 1);            Raster ras = image.getData(rect);            if (sourceBands != null) {                ras = ras.createChild(minX, row, width, 1, minX, row,                                      sourceBands);            }            ras.getPixels(minX, row, width, 1, samples);            if (image.getColorModel().isAlphaPremultiplied()) {                WritableRaster wr = ras.createCompatibleWritableRaster();                wr.setPixels(wr.getMinX(), wr.getMinY(),                             wr.getWidth(), wr.getHeight(),                             samples);                image.getColorModel().coerceData(wr, false);                wr.getPixels(wr.getMinX(), wr.getMinY(),                             wr.getWidth(), wr.getHeight(),                             samples);            }            // Reorder palette data if necessary            int[] paletteOrder = metadata.PLTE_order;            if (paletteOrder != null) {                for (int i = 0; i < numSamples; i++) {                    samples[i] = paletteOrder[samples[i]];                }            }            int count = bpp; // leave first 'bpp' bytes zero            int pos = 0;            int tmp = 0;            switch (bitDepth) {            case 1: case 2: case 4:                // Image can only have a single band                                int mask = samplesPerByte - 1;                for (int s = xOffset; s < numSamples; s += xSkip) {		    byte val = scale0[samples[s]];                    tmp = (tmp << bitDepth) | val;                    if ((pos++ & mask) == mask) {                        currRow[count++] = (byte)tmp;                        tmp = 0;                        pos = 0;                    }                }                // Left shift the last byte                if ((pos & mask) != 0) {                    tmp <<= ((8/bitDepth) - pos)*bitDepth;                    currRow[count++] = (byte)tmp;                }                break;            case 8:		if (numBands == 1) {		    for (int s = xOffset; s < numSamples; s += xSkip) {			currRow[count++] = scale0[samples[s]];			if (icm_gray_alpha != null) {                             currRow[count++] =                                 scale0[icm_gray_alpha.getAlpha(0xff & samples[s])];                        }		    }		} else {		    for (int s = xOffset; s < numSamples; s += xSkip) {			for (int b = 0; b < numBands; b++) {			    currRow[count++] = scale[b][samples[s + b]];			}		    }		}                break;            case 16:                for (int s = xOffset; s < numSamples; s += xSkip) {                    for (int b = 0; b < numBands; b++) {                        currRow[count++] = scaleh[b][samples[s + b]];                        currRow[count++] = scalel[b][samples[s + b]];                    }                }                break;            }            // Perform filtering            int filterType = rowFilter.filterRow(metadata.IHDR_colorType,                                                 currRow, prevRow,                                                 filteredRows,                                                 bytesPerRow, bpp);                        os.write(filterType);            os.write(filteredRows[filterType], bpp, bytesPerRow);                        // Swap current and previous rows            byte[] swap = currRow;            currRow = prevRow;            prevRow = swap;            pixelsDone += hpixels;            processImageProgress(100.0F*pixelsDone/totalPixels);            // If write has been aborted, just return;            // processWriteAborted will be called later            if (abortRequested()) {                return;            }        }    }    // Use sourceXOffset, etc.    private void write_IDAT(RenderedImage image) throws IOException {        IDATOutputStream ios = new IDATOutputStream(stream, 32768);        if (metadata.IHDR_interlaceMethod == 1) {            for (int i = 0; i < 7; i++) {                encodePass(ios, image,                           PNGImageReader.adam7XOffset[i],                           PNGImageReader.adam7YOffset[i],                           PNGImageReader.adam7XSubsampling[i],                           PNGImageReader.adam7YSubsampling[i]);                if (abortRequested()) {                    break;                }            }        } else {            encodePass(ios, image, 0, 0, 1, 1);        }        ios.finish();    }    private void writeIEND() throws IOException {        ChunkStream cs = new ChunkStream(PNGImageReader.IEND_TYPE, stream);        cs.finish();    }    // Check two int arrays for value equality, always returns false    // if either array is null    private boolean equals(int[] s0, int[] s1) {	if (s0 == null || s1 == null) {	    return false;	}	if (s0.length != s1.length) {	    return false;	}	for (int i = 0; i < s0.length; i++) {	    if (s0[i] != s1[i]) {		return false;	    }	}	return true;    }    // Initialize the scale/scale0 or scaleh/scalel arrays to    // hold the results of scaling an input value to the desired    // output bit depth    private void initializeScaleTables(int[] sampleSize) {	int bitDepth = metadata.IHDR_bitDepth;	// If the existing tables are still valid, just return	if (bitDepth == scalingBitDepth &&	    equals(sampleSize, this.sampleSize)) {	    return;	}		// Compute new tables	this.sampleSize = sampleSize;	this.scalingBitDepth = bitDepth;	int maxOutSample = (1 << bitDepth) - 1;	if (bitDepth <= 8) {	    scale = new byte[numBands][];	    for (int b = 0; b < numBands; b++) {		int maxInSample = (1 << sampleSize[b]) - 1;		int halfMaxInSample = maxInSample/2;		scale[b] = new byte[maxInSample + 1];		for (int s = 0; s <= maxInSample; s++) {		    scale[b][s] =			(byte)((s*maxOutSample + halfMaxInSample)/maxInSample);		}	    }	    scale0 = scale[0];	    scaleh = scalel = null;	} else { // bitDepth == 16	    // Divide scaling table into high and low bytes	    scaleh = new byte[numBands][];	    scalel = new byte[numBands][];	    for (int b = 0; b < numBands; b++) {		int maxInSample = (1 << sampleSize[b]) - 1;		int halfMaxInSample = maxInSample/2;		scaleh[b] = new byte[maxInSample + 1];		scalel[b] = new byte[maxInSample + 1];		for (int s = 0; s <= maxInSample; s++) {		    int val = (s*maxOutSample + halfMaxInSample)/maxInSample;		    scaleh[b][s] = (byte)(val >> 8);		    scalel[b][s] = (byte)(val & 0xff);		}	    }	    scale = null;	    scale0 = null;	}    }    public void write(IIOMetadata streamMetadata,                      IIOImage image,                      ImageWriteParam param) throws IIOException {        if (stream == null) {            throw new IllegalStateException("output == null!");        }        if (image == null) {            throw new IllegalArgumentException("image == null!");        }        if (image.hasRaster()) {            throw new UnsupportedOperationException("image has a Raster!");        }        RenderedImage im = image.getRenderedImage();        SampleModel sampleModel = im.getSampleModel();        this.numBands = sampleModel.getNumBands();        // Set source region and subsampling to default values        this.sourceXOffset = im.getMinX();        this.sourceYOffset = im.getMinY();        this.sourceWidth = im.getWidth();        this.sourceHeight = im.getHeight();        this.sourceBands = null;        this.periodX = 1;        this.periodY = 1;        if (param != null) {            // Get source region and subsampling factors            Rectangle sourceRegion = param.getSourceRegion();            if (sourceRegion != null) {                Rectangle imageBounds = new Rectangle(im.getMinX(),                                                      im.getMinY(),                                                      im.getWidth(),                                                      im.getHeight());                // Clip to actual image bounds                sourceRegion = sourceRegion.intersection(imageBounds);                sourceXOffset = sourceRegion.x;                sourceYOffset = sourceRegion.y;                sourceWidth = sourceRegion.width;                sourceHeight = sourceRegion.height;            }            // Adjust for subsampling offsets            int gridX = param.getSubsamplingXOffset();            int gridY = param.getSubsamplingYOffset();            sourceXOffset += gridX;            sourceYOffset += gridY;            sourceWidth -= gridX;            sourceHeight -= gridY;            // Get subsampling factors            periodX = param.getSourceXSubsampling();            periodY = param.getSourceYSubsampling();            int[] sBands = param.getSourceBands();            if (sBands != null) {                sourceBands = sBands;                numBands = sourceBands.length;            }        }        // Compute output dimensions        int destWidth = (sourceWidth + periodX - 1)/periodX;        int destHeight = (sourceHeight + periodY - 1)/periodY;        if (destWidth <= 0 || destHeight <= 0) {            throw new IllegalArgumentException("Empty source region!");        }        // Compute total number of pixels for progress notification        this.totalPixels = destWidth*destHeight;        this.pixelsDone = 0;        // Create metadata        IIOMetadata imd = image.getMetadata();        if (imd != null) {            metadata = (PNGMetadata)convertImageMetadata(imd,                               ImageTypeSpecifier.createFromRenderedImage(im),                                                         null);        } else {            metadata = new PNGMetadata();        }        if (param != null) {            // Use Adam7 interlacing if set in write param            switch (param.getProgressiveMode()) {            case ImageWriteParam.MODE_DEFAULT:                metadata.IHDR_interlaceMethod = 1;                break;            case ImageWriteParam.MODE_DISABLED:                metadata.IHDR_interlaceMethod = 0;                break;                // MODE_COPY_FROM_METADATA should alreay be taken care of                // MODE_EXPLICIT is not allowed            }        }        // Initialize bitDepth and colorType        metadata.initialize(new ImageTypeSpecifier(im), numBands);        // Overwrite IHDR width and height values with values from image        metadata.IHDR_width = destWidth;        metadata.IHDR_height = destHeight;        this.bpp = numBands*((metadata.IHDR_bitDepth == 16) ? 2 : 1);	// Initialize scaling tables for this image	initializeScaleTables(sampleModel.getSampleSize());        clearAbortRequest();        processImageStarted(0);        try {            write_magic();            write_IHDR();            write_cHRM();            write_gAMA();            write_iCCP();            write_sBIT();            write_sRGB();                    write_PLTE();                        write_hIST();            write_tRNS();            write_bKGD();                        write_pHYs();            write_sPLT();            write_tIME();            write_tEXt();            write_iTXt();            write_zTXt();                        writeUnknownChunks();                        write_IDAT(im);            if (abortRequested()) {                processWriteAborted();            } else {                // Finish up and inform the listeners we are done                writeIEND();                processImageComplete();            }        } catch (IOException e) {            throw new IIOException("I/O error writing PNG file!", e);        }    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -