Reputation: 6755
I have the following problem. I started with a bitmap transformation routine that works flawlessly for any kind of transformation I can throw at it.
Bitmap transform(Bitmap src) {
// ... any kind of transformation , for example GAMMA
double gama = 0.8;
int[] tR = new int[256];
int[] gG = new int[256];
int[] tB = new int[256];
for(int i = 0; i < 256; ++i) {
tR[i] = (int)Math.min(255, (int)((255.0 * Math.pow(i / 255.0, 1.0 / gama)) + 0.5));
tG[i] = (int)Math.min(255, (int)((255.0 * Math.pow(i / 255.0, 1.0 / gama)) + 0.5));
tB[i] = (int)Math.min(255, (int)((255.0 * Math.pow(i / 255.0, 1.0 / gama)) + 0.5));
}
// apply transformation to the old bitmap -> bmOut
int wid = src.getWidth(), hei = src.getHeight();
Bitmap bmOut = Bitmap.createBitmap(wid, hei, src.getConfig());
int A, R, G, B;
for(int x = 0; x < wid; x++) {
for(int y = 0; y < hei; y++) {
int pixel = src.getPixel(x, y);
A = Color.alpha(pixel);
R = tR[Color.red(pixel)];
G = tG[Color.green(pixel)];
B = tB[Color.blue(pixel)];
bmOut.setPixel(x, y, Color.argb(A, R, G, B));
}
}
return bmOut;
}
But it is PAINFULLY slow - caused by the getPixel() / setPixel() brothers, sisters. No problem, says I, I'll just use a memory buffer (like in the old StretchBlt() days). So, I did a MAJOR rewrite, creating the following gem of software engineering :)
Bitmap transform(Bitmap src) {
// ... transformation array are built here
// apply transformation
int wid = src.getWidth(), hei = src.getHeight();
Bitmap bmOut = Bitmap.createBitmap(wid, hei, src.getConfig());
int[] pixs = new int[wid*hei]; // changed
src.getPixels(pixs, 0, wid, 0, 0, wid, hei); // changed
int A, R, G, B;
for(int x = 0; x < wid; x++) {
for(int y = 0; y < hei; y++) {
int off = ( x * y ) + y; // changed
int pixel = pixs[off]; // changed
A = Color.alpha(pixel);
R = tR[Color.red(pixel)];
G = tG[Color.green(pixel)];
B = tB[Color.blue(pixel)];
pixs[off] = Color.argb(A, R, G, B); // changed
}
}
bmOut.setPixels(pixs, 0, wid, 0, 0, wid, hei); // changed
return bmOut;
}
Runs fast, even gets a correct result IF THERE IS NO TRANSFORMATION. But it falls apart if I try to massage the pixels (apply transformations). So I did comparison of ARGB pixels from getPixel() vs array of pixels values from getPixels(...) and they are different (well, the first 2 are the same, which leaves me with about zillion that are not).
array getPixel
a r g b a r g b
------------------
ff65340b ff65340b
ff64330a ff64330a
ff66320b ff63320a
ff65310a ff613008
ff66300c ff62300d
ff67310d ff62300d
ff68300d ff622d0d
ff69310e ff5f2a0a
....
Anybody knows what I'm doing wrong this time? I am not willing to give up the speed of the mem-array solution yet. Thanks, sean
Upvotes: 2
Views: 223
Reputation: 2488
It should be
int off = ( y * wid ) + x;
By the way, I think the two loops is unnecessary, you can simply do:
for (int off = pixs.length - 1; off >= 0; off--)
Upvotes: 1