vxh.viet
4/24/2016 - 12:47 PM

How to Apply Color LUT to bitmap images for filter effects in Android?

How to Apply Color LUT to bitmap images for filter effects in Android?

Source: StackOverflow, StackOverflow

Question: How to Apply Color LUT to bitmap images for filter effects in Android?

Answer:

    final static int X_DEPTH = 64;
    final static int Y_DEPTH = 64; //One little square in the LUT has 64x64 pixels in it
    final static int ROW_DEPTH = 8;
    final static int COLUMN_DEPTH = 8; // the LUT consists of 8x8 little squares
    final static int COLOR_DISTORTION = 4; // for new LUT size, update this so 255/COLOR_DISTORTION < X_DEPTH since we dont want to look for color outside of 1 row of the LUT square (0-63).
    
public Bitmap applyLutToBitmap(Bitmap src, Bitmap lutBitmap) {
        int mWidth = src.getWidth();
        int mHeight = src.getHeight();
        int[] imgArray = new int[mWidth * mHeight];
        src.getPixels(imgArray, 0, mWidth, 0, 0, mWidth, mHeight);

        int lutWidth = lutBitmap.getWidth();
        int lutArray[] = new int[lutWidth * lutBitmap.getHeight()];
        lutBitmap.getPixels(lutArray , 0, lutWidth, 0, 0, lutWidth, lutBitmap.getHeight());

        int R, G, B;
        for(int y = 0; y < mHeight; y++) {
            for(int x = 0; x < mWidth; x++) {

                int index = y * mWidth + x;

                // Get pixels by R, G, B
                int r = Color.red(imgArray[index]) / COLOR_DISTORTION;
                int g = Color.green(imgArray[index]) / COLOR_DISTORTION;
                int b = Color.blue(imgArray[index]) / COLOR_DISTORTION;

                //logic for altering the pixels;
                int lutIndex = getLutIndex(lutWidth, r, g, b);

                R = Color.red(lutArray[lutIndex]);
                G = Color.green(lutArray[lutIndex]);
                B = Color.blue(lutArray[lutIndex]);
                imgArray[index] = 0xff000000 | (R << 16) | (G << 8) | B;
            }
        }
        Bitmap filteredBitmap = Bitmap.createBitmap(mWidth, mHeight, src.getConfig());
        filteredBitmap.setPixels(imgArray, 0, mWidth, 0, 0, mWidth, mHeight);
        return filteredBitmap;
    }

    //the magic happens here
    private int getLutIndex(int lutWidth, int redDepth, int greenDepth, int blueDepth) {
        /*int lutX = (greenDepth % ROW_DEPTH) * X_DEPTH + blueDepth;
        int lutY = (greenDepth / COLUMN_DEPTH) * Y_DEPTH + redDepth;
        return lutY * lutWidth + lutX;*/

        int lutX = (blueDepth % ROW_DEPTH) * X_DEPTH + redDepth;
        int lutY = (blueDepth / COLUMN_DEPTH) * Y_DEPTH + greenDepth;
        return lutY * lutWidth + lutX;
    }