Here you can find the source of paletteSwapARGB8(Color[] colorSet, Color clearToColorRequested, BufferedImage argbMappedBufferedImage)
Parameter | Description |
---|---|
colorSet | Color[] - that processes [1..4] up to four palette colors. 3 or less uses R,G,B passes only. 4 uses A,R,G,B and ignores anything more. |
clearToColorRequested | - Color - A color to Blend with the First Translucent Pass - Optional |
argbMappedBufferedImage | - BufferedImage - The image containing Channels as Alpha for the Palette |
public static BufferedImage paletteSwapARGB8(Color[] colorSet, Color clearToColorRequested, BufferedImage argbMappedBufferedImage)
//package com.java2s; //License from project: Open Source License import java.awt.Color; import java.awt.image.BandedSampleModel; import java.awt.image.BufferedImage; import java.awt.image.DataBuffer; import java.awt.image.DataBufferFloat; import java.awt.image.Raster; import java.awt.image.WritableRaster; public class Main { /**//www.j a va2 s .c om * This method transforms the inputed BufferedImage by the supplied Color[]. * The behavior treats the Color[] as Ordered Passes A, R, G, B for .length * 4 or more. It treats it as Ordered Passes R, G, B only for .length 3 or * less. * * @param colorSet Color[] - that processes [1..4] up to four palette * colors. 3 or less uses R,G,B passes only. 4 uses A,R,G,B and ignores * anything more. * @param clearToColorRequested - Color - A color to Blend with the First * Translucent Pass - Optional * @param argbMappedBufferedImage - BufferedImage - The image containing * Channels as Alpha for the Palette * @return BufferedImage - a new BufferedImage() transformed by the palette. */ public static BufferedImage paletteSwapARGB8(Color[] colorSet, Color clearToColorRequested, BufferedImage argbMappedBufferedImage) { if (argbMappedBufferedImage == null) { return null; //S.E.P. } final Color BLACK_NO_ALPHA = new Color(0x00000000); final Color WHITE_NO_ALPHA = new Color(0x00FFFFFF); final int ALPHA = 3; // this is some static mapping for... final int RED = 0; // readability in the following... final int GREEN = 1; // Magic code section of band processing. final int BLUE = 2; final int[] orderedBands = { ALPHA, RED, GREEN, BLUE }; //first we prep a cmap with blank passes and Color[] cMap = { BLACK_NO_ALPHA, BLACK_NO_ALPHA, BLACK_NO_ALPHA, BLACK_NO_ALPHA }; boolean clearColorFound = false; Color clearToColor = BLACK_NO_ALPHA; if (colorSet != null) { //if we get a null colorSet... it's all mapped to clear. if (colorSet.length > cMap.length) { // if colorSet is more than 4, we only proces up to 4 for (int i = 0; i < cMap.length; i++) { if (colorSet[i] != null) { if (!clearColorFound) { clearColorFound = true; clearToColor = colorSet[i]; } cMap[orderedBands[i]] = colorSet[i]; // and finally, if any of the Colors are null... invisible pass... } } } else { int startOffset = 0; if (colorSet.length < 4) // if less than standard size, assume RGB model { startOffset++; // and "blank" the alpha color pass. } for (int i = 0; i < colorSet.length; i++) { if (colorSet[i] != null) { if (!clearColorFound) { clearColorFound = true; clearToColor = colorSet[i]; } cMap[orderedBands[i + startOffset]] = colorSet[i]; } } } } // finally adjust the clearToColor if one was requested if (clearToColorRequested != null) { clearToColor = clearToColorRequested; } //Next we'll switch to Rasters to easily handle floating point precision // operations upon the individual channels. WritableRaster outRaster, inRaster; int w = argbMappedBufferedImage.getWidth(); int h = argbMappedBufferedImage.getHeight(); BandedSampleModel inSM = new BandedSampleModel( DataBuffer.TYPE_FLOAT, w, h, 4); DataBufferFloat inDBF = new DataBufferFloat((w * h), 4);//4 banks, and total size inRaster = Raster.createWritableRaster(inSM, inDBF, null); // that null just means point 0, 0 (top/left) outRaster = inRaster.createCompatibleWritableRaster(w, h); float[] cMaptoFlArray, outColortoFlArray, clearColortoFlArray; float inBandAsAlpha; Color paletteColor; // now we convert from W/E the argbMappedBufferedImage's format to // our normalized [0f..1f] RGBA raster outColortoFlArray = new float[] { 0f, 0f, 0f, 0f }; // or new float[4]... w/e clearColortoFlArray = clearToColor.getRGBComponents(new float[4]); clearColortoFlArray[ALPHA] = 0f; for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++) { int packedPixel = argbMappedBufferedImage.getRGB(x, y); int testing; float ftesting; //outColortoFlArray[ALPHA] = (((packedPixel >> 24) & 0xFF) / 255); testing = packedPixel; testing = testing >> 24; testing = testing & 0xFF; ftesting = testing; ftesting = ftesting / 255; outColortoFlArray[ALPHA] = ftesting; //outColortoFlArray[RED] = (((packedPixel >> 16) & 0xFF) / 255); testing = packedPixel; testing = testing >> 16; testing = testing & 0xFF; ftesting = testing; ftesting = ftesting / 255; outColortoFlArray[RED] = ftesting; //outColortoFlArray[GREEN] = (((packedPixel >> 8) & 0xFF) / 255); testing = packedPixel; testing = testing >> 8; testing = testing & 0xFF; ftesting = testing; ftesting = ftesting / 255; outColortoFlArray[GREEN] = ftesting; //outColortoFlArray[BLUE] = ( (packedPixel & 0xFF) / 255); testing = packedPixel; testing = testing & 0xFF; ftesting = testing; ftesting = ftesting / 255; outColortoFlArray[BLUE] = ftesting; inRaster.setPixel(x, y, outColortoFlArray); outRaster.setPixel(x, y, clearColortoFlArray); } } // next, we process all bands in order - a "band" being one channel of A,R,G,B. // as each band is processed the outRaster keeps getting "resampled" to apply // the next band properly. all values are considered normalized [0f..1f] for (int band : orderedBands) { paletteColor = cMap[band]; cMaptoFlArray = paletteColor.getRGBComponents(new float[4]);// this nullifies translucency if (paletteColor != BLACK_NO_ALPHA) { for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++) { //inBandAsAlpha = inRaster.getSample(x, y, band); inBandAsAlpha = inRaster.getSampleFloat(x, y, band); outColortoFlArray = outRaster.getPixel(x, y, new float[4]); outColortoFlArray[RED] = (outColortoFlArray[RED] * (1f - (inBandAsAlpha * cMaptoFlArray[ALPHA]))) + (cMaptoFlArray[RED] * (inBandAsAlpha * cMaptoFlArray[ALPHA])); outColortoFlArray[GREEN] = (outColortoFlArray[GREEN] * (1f - (inBandAsAlpha * cMaptoFlArray[ALPHA]))) + (cMaptoFlArray[GREEN] * (inBandAsAlpha * cMaptoFlArray[ALPHA])); outColortoFlArray[BLUE] = (outColortoFlArray[BLUE] * (1f - (inBandAsAlpha * cMaptoFlArray[ALPHA]))) + (cMaptoFlArray[BLUE] * (inBandAsAlpha * cMaptoFlArray[ALPHA])); outColortoFlArray[ALPHA] = (outColortoFlArray[ALPHA] * (1f - (inBandAsAlpha * cMaptoFlArray[ALPHA]))) + (cMaptoFlArray[ALPHA] * (inBandAsAlpha * cMaptoFlArray[ALPHA])); outRaster.setPixel(x, y, outColortoFlArray); } } } } //then we convert n' ship BufferedImage returnBI = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++) { outColortoFlArray = outRaster.getPixel(x, y, new float[4]); int packedColor = ((int) (outColortoFlArray[ALPHA] * 255f) << 24) | ((int) (outColortoFlArray[RED] * 255f) << 16) | ((int) (outColortoFlArray[GREEN] * 255f) << 8) | ((int) (outColortoFlArray[BLUE] * 255f)); returnBI.setRGB(x, y, packedColor); } } return returnBI; } public static BufferedImage paletteSwapARGB8(Color[] colorSet, BufferedImage argbMappedBufferedImage) { return paletteSwapARGB8(colorSet, null, argbMappedBufferedImage); } }