1

I have the image_source that is the source bitmap with some picture and image_new — temporary bitmap

I do this code, that makes image_source be anaglyph background layer:

int [] pixel = {0x0, 0x0, 0x0};
int [] image_params = {image_source.getWidth() - 2 * anaglyph_amplitude, image_source.getHeight()};
Bitmap image_new = Bitmap.createScaledBitmap(image_source, image_params[0], image_params[1], false);
for(int i = 0; i < image_params[0]; ++i)
    for(int j = 0; j < image_params[1]; ++j) {
        pixel[0] = image_source.getPixel(i, j);
        pixel[1] = image_source.getPixel(i + 2 * anaglyph_amplitude, j);
        pixel[2] = pixel[0] + pixel[1] % 0x10000 - pixel[0] % 0x10000;
        image_new.setPixel(i, j, pixel[2]);
    }
image_source = Bitmap.createBitmap(image_new);
image_new = null;

Then image_source is drawn to canvas (drawing to canvas at ones is not available).

The problem is that this programm takes about 5 seconds to process image with 1000x1000 size on smart Android device.

Are there any other ways to run bitmap pixels?

Finesse
  • 9,793
  • 7
  • 62
  • 92
  • i have the same problem while image processing. it will take too much time to process. i want to process on scollbar (on seek bar progress change). – Hiren Dabhi Jan 04 '12 at 06:20
  • See answer below, but short summary is to use getPixels() to grab a bunch of pixels at once. – user949300 Jan 04 '12 at 19:36

4 Answers4

1

There is some performance enhancement for snippet code. I am not sure it is enough for you.

First change

pixel[2] = pixel[0] + (pixel[1] & 0xFFFF) - (pixel[0] & 0xFFFF);

instead of

pixel[2] = pixel[0] + pixel[1] % 0x10000 - pixel[0] % 0x10000;

-

pixel[1] = image_source.getPixel(i + (anaglyph_amplitude<<1), j);

instead of

pixel[1] = image_source.getPixel(i + 2 * anaglyph_amplitude, j);
Erdinç Taşkın
  • 1,548
  • 3
  • 17
  • 28
  • No visible difference. I made experiment: I changed `pixel[0] = image_source.getPixel(i, j);` insted of the whole code inside the loop; the result was the same – Finesse Jan 04 '12 at 09:49
  • Maybe it's able to get arrray of whole pixels colors on a quick single operation? – Finesse Jan 04 '12 at 09:51
  • Diagnose real time consume part of your code. print timestamp before loop, after loop and also after createBitmap() . – Erdinç Taşkın Jan 04 '12 at 10:59
1

Another minor tweak. In the inner loop, no reason to use an array for pixel[1] etc. Have three ints, p0, p1 and p2.

EDIT ADDED

I'm less familiar with Android than Swing, but I was hoping that Android's Bitmap has a "get me a bunch of pixels at a time" method similar to a Raster. It does.

I think you should be using the Bitmap method javadocs link here

public void getPixels (int[] pixels, int offset, int stride, int x, int y, int width, int height)

If you have the memory available, get all 1,000,000 at once.

user949300
  • 15,364
  • 7
  • 35
  • 66
0

You could cache the calculation of 2 * anaglyph_amplitude so it has not to be calculated on each iteration.

Kai
  • 38,985
  • 14
  • 88
  • 103
  • @user94 On Hotspot c2? Certainly, but do you have any idea how good the JIT for android is? (and that's assuming a android2.2+ release) No idea if that does CSE. – Voo Jan 04 '12 at 19:09
0

Here is solution: I get array of pixels and worked with it.

int [] pixel = {0x0, 0x0, 0x0};
int [] pixels_old, pixels_new;
int [] params = {image_source.getWidth(), image_source.getHeight()};
int [] image_params = {image_source.getWidth() - 2 * anaglyph_amplitude, image_source.getHeight()};
pixels_old = new int[params[2] * params[3]];
pixels_new = new int[image_params[0] * image_params[1]];
image_source.getPixels(pixels_old, 0, params[2], 0, 0, params[2], params[3]); 
image_source = null;
for(int i = 0; i < image_params[0]; ++i)
    for(int j = 0; j < image_params[1]; ++j) {
        pixel[0] = pixels_old[i + j * params[2]];
        pixel[1] = pixels_old[i + (anaglyph_amplitude<<1) + j * params[2]];
        pixel[2] = pixel[0] + (pixel[1] & 0xFFFF) - (pixel[0] & 0xFFFF);
        pixels_new[i + j * image_params[0]] = pixel[2];
    }
pixels_old = null;
image_source = Bitmap.createBitmap(pixels_new, image_params[0], image_params[1], Bitmap.Config.ARGB_8888);
pixels_new = null;
Finesse
  • 9,793
  • 7
  • 62
  • 92