So I've written this piece of code to shift the hues in a specific part of the spectrum.
I tried my best to optimize it as much as possible: used LUT, downsampled image for the preview and limited the color operations to the parts where needed.
I get pretty good results on the PC, with ~1ms for the shiftHue() function on the downsampled image and ~12ms for the original image. The problem is when I run it on my android phone I only get ~150ms and ~800ms respectively. Is there anything I am missing which can be further optimized? or should I just downsample further for the preview?
(
note: I think my question is a general programming question and not android specific, hence posting it here. Am I right?)
here is the code:
- PImage bigImg;
- PImage smallImg;
- float hueLUT[];
- float hueShift;
- void setup() {
- size(480, 854);
- colorMode(HSB, 1);
- imageMode(CENTER);
- initHueLUT();
- bigImg = loadImage("big.png");
- smallImg = loadImage("small.png");
- image(bigImg, width/2, height/2);
- }
- void draw() {
- if (mousePressed) {
- hueShift = map((mouseX), 0, width, -3, 3);
- image(shiftHue(smallImg), width/2, height/2, bigImg.width, bigImg.height);
- }
- }
- void mouseReleased() {
- image(shiftHue(bigImg), width/2, height/2);
- }
- PImage shiftHue(PImage in) {
- int w = in.width;
- int h = in.height;
- PImage out = createImage(w, h, HSB);
- in.loadPixels();
- for (int i = 0; i < in.width; i++) {
- for (int j = 0; j < in.height; j++) {
- int index = i + j*in.width;
- color c = in.pixels[index];
- float H = hue(c);
- int hueIndex = int(H*256);
- if (hueLUT[hueIndex]>0) {
- float S = saturation(c);
- float B = brightness(c);
- H = (hueShift * hueLUT[hueIndex]+H);
- if (H<0) {
- if (H<-1) H = 2+H;
- else H = 1+H;
- }
- else {
- if (H>2) H = H-2;
- else {
- if (H>1) H = H-1;
- }
- }
- out.pixels[index] = color(H, S, B);
- }
- else {
- out.pixels[index] = in.pixels[index];
- }
- }
- }
- out.updatePixels();
- return out;
- }
- void initHueLUT() {
- hueLUT = new float[256];
- for (int i = 0; i<256; i++) {
- hueLUT[i] = 1.1*pow(sin(PI*(i/256f)-HALF_PI-.12), 60)-.1;
- }
- }
Thanks in advance!
EDIT: Replaced the double for loops up there with " for (int i = 0; i < in.pixels.length; i++) " and it got ~30ms faster. anything else?
1