Question

I have this working code which reads in a 700x700 RGB24 TIF file and places it into display memory. The line which assigns the pixelARGB value appears to be extremely inefficient, this code takes 3-4 seconds to redraw the screen. Is there a way I can avoid the shifting and oring and just place the byte values into the correct position within the 32 bit word? In other languages I have done this with "overlayed variables" or "variant records" or such. Cannot find this in Java. Thank you.

for (y=0; y<700; y++) { // for each line
    i = 0;
    for (x=0; x<700; x++) { // for each dot
        red = lineBuf[i++] & 0xFF;
        green = lineBuf[i++] & 0xFF;
        blue = lineBuf[i++]& 0xFF;
        pixelARGB = 0xFF000000 | (red << 16)| (green << 8) | blue;
        this_g.setPixel(x + BORDER, y + BORDER, pixelARGB);
    }
    size=is.read(lineBuf,0,2100);
}
Was it helpful?

Solution

There is at least one way to convert your TIFF image data buffer into a Bitmap more efficiently, and there is an optimization that can possibly be made.

1. Use an int[] array instead of pixel copies:

You still have to calculate each pixel individually, but set them in an int[] array. It is the setPixel() function that is taking all your time.

Example:

final int w = 700;
final int h = 700;
final int n = w * h;
final int [] buf = new int[n];
for (int y = 0; y < h; y++) {
    final int yw = y * w;
    for (int x = 0; x < w; x++) {
        int i = yw + x;
        // Calculate 'pixelARGB' here.
        buf[i] = pixelARGB;
    }
}
Bitmap result = Bitmap.createBitmap(buf, w, h, Bitmap.Config.ARGB_8888);

2. Resize within your Loop:

This is not very likely, but in case your destination ImageView for the result image is known to be smaller than the source image, which is 700x700 in your question, then you can resize within your for loop for an extremely high performance increase.

What you have to do is loop through your destination image pixels, calculate the pixel x, y values you need from your source image, calculate the pixelARGB value for only those pixels, populate a smaller int[] array, and finally generate a smaller Bitmap. Much. Faster.

You can even enhance the resize quality with a homebrew cubic interpolation of the four nearest source pixels for each destination pixel, but I think you will find this unnecessary for display purposes.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top