Java BufferedImage Operation paletteSwapARGB8(Color[] colorSet, Color clearToColorRequested, BufferedImage argbMappedBufferedImage)

Here you can find the source of paletteSwapARGB8(Color[] colorSet, Color clearToColorRequested, BufferedImage argbMappedBufferedImage)

Description

This method transforms the inputed BufferedImage by the supplied Color[].

License

Open Source License

Parameter

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

Return

BufferedImage - a new BufferedImage() transformed by the palette.

Declaration

public static BufferedImage paletteSwapARGB8(Color[] colorSet,
        Color clearToColorRequested,
        BufferedImage argbMappedBufferedImage) 

Method Source Code

//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);
    }
}

Related

  1. optimizeForGraphicsHardwareIfRequired(BufferedImage image)
  2. optimizeImage(BufferedImage image)
  3. otsuTreshold(BufferedImage original)
  4. output(BufferedImage image, OutputStream out)
  5. outPutImage(BufferedImage bufferedimage, String targetPath)
  6. palettize(BufferedImage img, int maxEntries)
  7. performRescaleOperation(BufferedImage image, float scale, float offset)
  8. prepareModel(BufferedImage model)
  9. recolor(BufferedImage img, int newColor)