Applying a Color Transformation to very Pixel of a texture (Libgdx)

0

A game I am currently developing uses a 5x5 matrix to change the colors of the image on a per pixel basis. I was wondering if anyone has developed an extremely fast algorithm for something like this.

For every Pixel(setPixel(sourcePixel * Matrix))

I have built my own algorithm for this by getting and setting pixels on pixmap then drawing a new pixmap from this through iterating every pixel with set/get pixel. I have found a reasonably fast algorithm for this (150 million pixels ~3 seconds), but I was thinking of another idea rather than using the pixmap but I am unsure of how to implement this. Libgdx provides a FileHandle.readBytes() method that reads image files (in my case PNG) to byte arrays. My thought was rather than creating a pixmap, read the byte array while iterating the pixels. While iterating I would be drawing a new pixmap meaning their really is no point for me to make one for the base pixmap in the first place. With tests I found that with my current algorithm, 70% of the time it takes is from the method (PixMap.getPixel(x, y), and I could bypass this by straight reading the byte array. I have looked into PNG readers for byte array's online but to no avail. Note I am unable to use ImageIO due it being an android based game. Would it make it faster by reading the byte array data while iterating/ is it possible to do this?

In the code below, JList is basically a HashMap in this context

 private static JList<Integer, Pixmap> colorShiftImage(Pixmap p, JList<Integer, float[][]> cms){
        JList<float[][], Pixmap> tempList = new JList<>();
        for(int i = cms.size() - 1; i > -1; --i){
            tempList.add(cms.getInt(i), new Pixmap(p.getWidth(), p.getHeight(), Pixmap.Format.RGBA8888));
        }
        for(int y = p.getHeight() - 1; y > -1; --y){
            for(int x = p.getWidth() - 1; x > -1; --x){
                int v = p.getPixel(x, y);
                if(v != 0) {
                    r = ((v & 0xff000000) >>> 24);
                    g = ((v & 0x00ff0000) >>> 16);
                    b = ((v & 0x0000ff00) >>> 8);
                    a = ((v & 0x000000ff));
                    for(int i = tempList.size() - 1; i > -1; --i) {
                        float[][] c = tempList.getIDList().get(i);
                        tempList.getInt(i).drawPixel(x, y, (((l((r * c[0][0]) + (c[1][0] * g) + (c[2][0] * b) + (c[3][0] * a) + c[4][0])) << 24)
                                | ((l((r * c[0][1]) + (c[1][1] * g) + (c[2][1] * b) + (c[3][1] * a) + c[4][1])) << 16)
                                | ((l((r * c[0][2]) + (c[1][2] * g) + (c[2][2] * b) + (c[3][2] * a) + c[4][2])) << 8)
                                | ((l((r * c[0][3]) + (c[1][3] * g) + (c[2][3] * b) + (c[3][3] * a) + c[4][3])))));
                    }
                }
            }
        }
        JList<Integer, Pixmap> returnL = new JList<>();
        for(int i = tempList.size() - 1; i > - 1; --i){
            returnL.add(cms.getIDList().get(i), tempList.getInt(i));
        }
        return returnL;
    }




  public static int l(float v){
        if(v < 0)return 0;
        else if(v > 255)return 255;
        return (int) v;
    }
libgdx
colormatrix
asked on Stack Overflow Jul 15, 2020 by JFJB Games • edited Jul 16, 2020 by JFJB Games

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0