Reputation: 5900
I'm developing an image processing library for Android which has ability to apply adjustments to image.
At first, I process each bits like this:
public int[] getProcessedPixels(int[] pixels) {
int a, r, g, b;
for(int i = 0; i < pixels.length; i++) {
a = Color.alpha(pixels[i]);
r = Color.red(pixels[i]);
g = Color.green(pixels[i]);
b = Color.blue(pixels[i]);
a = doSomethingWithThisChannel(a);
r = doSomethingWithThisChannel(r);
g = doSomethingWithThisChannel(g);
b = doSomethingWithThisChannel(b);
// Merge back all 4 channels to pixel value
pixels[i] = Color.argb(a, r, g, b);
}
return pixels;
}
// Usage sample
int[] pixels = bitmap.getAllPixels(); // each pixels is hexa 0xAARRGGBB
int[] resultPixels = getProcessedPixels(pixels); // it returns result pixels
Since I'm developing a library, I want to let developers who use it to be able to apply "doSomethingWithThisChannel" method to any channel(s) as needed
I want to change the method like this (it's a copy of the above method, but simplified):
public int[] getProcessedPixels(int[] pixels) {
// assume process all channels if not specified
return getProcessedPixels(pixels, Channel.ALL);
}
public int[] getProcessedPixels(int[] pixels, int channels) {
int a, r, g, b;
for(int i = 0; i < pixels.length; i++) {
pixels[i] = doSomethingWithTHESEChannels(pixels[i], channels);
}
return pixels;
}
// Usage sample
int channels = Channel.RED | Channel.GREEN; // ONLY apply processing to RED & GREEN channels
int[] pixels = bitmap.getAllPixels(); // each pixels is hexa 0xAARRGGBB
int[] resultPixels = getProcessedPixels(pixels, channels);
This is my static class to define "bitmasks" (cmiiw) for each ARGB color channel I used in the code above:
public class Channel {
public static final int NONE = 0x00000000;
public static final int ALL = 0xffffffff;
public static final int ALPHA = 0xff000000;
public static final int RED = 0x00ff0000;
public static final int GREEN = 0x0000ff00;
public static final int BLUE = 0x000000ff;
}
Do you have any suggestion how should I implement doSomethingWithTHESEChannels
method above? I'm pretty sure it will involve bitmask/bit-manipulation.
Upvotes: 0
Views: 189
Reputation: 3154
Here is a implementation of the doSomethingWithTHESEChannels method as per your design :
private int doSomethingWithTHESEChannels(int i, int channels) {
if (Channel.NONE == channels) {
return i;
}
int a, r, g, b;
a = (i & Channel.ALPHA) >> 24;
r = (i & Channel.RED) >> 16;
g = (i & Channel.GREEN) >> 8;
b = i & Channel.BLUE;
int cur = channels & Channel.ALL;
if (cur == Channel.ALL) {
System.out.println("all found");
a = transform(a);
r = transform(r);
g = transform(g);
b = transform(b);
} else {
cur = channels & Channel.ALPHA;
if (cur == Channel.ALPHA) {
System.out.println("alpha found");
a = transform(a);
}
cur = channels & Channel.RED;
if (cur == Channel.RED) {
System.out.println("red found");
r = transform(r);
}
cur = channels & Channel.GREEN;
if (cur == Channel.GREEN) {
System.out.println("green found");
g = transform(g);
}
cur = channels & Channel.BLUE;
if (cur == Channel.BLUE) {
System.out.println("blue found");
b = transform(b);
}
}
return (a << 24 | r << 16 | g << 8 | b);
}
The transform method is the operation to be applied to a channel. The Sysouts are just for testing purposes. You may change the type of a,r,g,b variables to byte with proper type-castings if needed.
However, I suggest you to move the above channel detection blocks(if conditions) to the getProcessedPixels method itself. Then you can pass the entire pixels array to a transform method. This way you will eliminate the redundant condition checks for each pixel. If you need hint on this, just leave a reply, I will update the answer.
Upvotes: 1