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;
}
User contributions licensed under CC BY-SA 3.0