Spotlight
Spotlight

Reputation: 1299

Remove transparent bound from Bitmap

I'm working on a method to remove the transparent bounds of a Bitmap. The method looks like this:

private static final int STEP = 4;//Don't check all the pixel, only a sampling

private Bitmap clipTransparent(Bitmap image) {
    int x1, x2, y1, y2;
    final int width = image.getWidth();
    final int height = image.getHeight();
    for (x1 = 0; x1 < width - 1; x1 += STEP) {
        if (checkColumn(image, x1)) {
            break;
        }
    }
    x1 = Math.max(0, x1 - STEP);
    for (x2 = width - 1; x2 > x1; x2 -= STEP) {
        if (checkColumn(image, x2)) {
            break;
        }
    }
    x2 = Math.min(width, x2 + STEP);

    for (y1 = 0; y1 < height - 1; y1 += STEP) {
        if (checkRow(x1, x2, image, y1)) {
            break;
        }
    }
    y1 = Math.max(0, y1 - STEP);

    for (y2 = height - 1; y2 > 0; y2 -= STEP) {
        if (checkRow(x1, x2, image, y2)) {
            break;
        }
    }
    y2 = Math.min(height, y2 + STEP);
    try {
        image = Bitmap.createBitmap(image, x1, y1, x2 - x1, y2 - y1);
    } catch (Throwable t) {
        t.printStackTrace();
    }
    return image;
}

private boolean checkColumn(Bitmap image, int x1) {
    for (int y = 0; y < image.getHeight(); y += STEP) {
        if (Color.alpha(image.getPixel(x1, y)) > 0) {
            return true;
        }
    }
    return false;
}

private boolean checkRow(int x1, int x2, Bitmap image, int y1) {
    for (int x = x1; x < x2; x += STEP) {
        if (Color.alpha(image.getPixel(x, y1)) > 0) {
            return true;
        }
    }
    return false;
}

It works great, but not as fast as I would like it to be. The bottleneck of the code is to get the color of a pixel.

Now I read that value by calling image.getPixel(x, y), but looking at the source code of Android, getPixel checks the indexes and does other stuff that slows the code down (x>=0 && x<getWidth() && y>=0 && y<getHeight() && !isRecycled)...

Is there a way to access the pixel data without any index check or other useless stuff (useless in my case of course)?

PS: I already tryed to use getPixels() that returns a int array containing all the colors. But the image is big and allocating all the memory triggers a GC... the result was an even slower method

Upvotes: 0

Views: 714

Answers (1)

Kirill Rakhman
Kirill Rakhman

Reputation: 43791

According to the docs you can pass an array to getPixels() which you can later reuse. This way no GC should ever happen.

Upvotes: 1

Related Questions