Android: Exception applying a ColorMatrixColorFilter to a Paint object, but only for certain Bitmaps

387 Views Asked by At

I am kind of a beginner to Android programming, but I've spent a lot of time pinning this down, so hopefully someone knows what's going on. My app has a bunch of Thing objects, each of which has a bitmap, and each one changes the bitmap somehow (change the color, size, etc). This all worked fine with some "test" bitmaps I made in MS Paint (saved as .png files). However, when I replaced them with nicer pictures made in GIMP, the app started crashing.

Eventually I figured out that the app would only crash if the .png image is saved with "Save background color" checked in GIMP. I need this, as some of these pictures need to be partially transparent so they can be overlaid. However: the crazy thing is, it is not crashing when I try to overlay an image, or create one, it's crashing when I apply the ColorMatrixColorFilter to the Paint object.

I don't understand how that can be. It never gets far enough to actually apply the Paint object to anything, so why would one image file work, but another one wouldn't? The crash is a RuntimeException in ActivityThread.performLauncActivity and I haven't been able to find out anything more about it.

Here's some pseudocode of exactly what I'm doing and where it's crashing.

Questions: 1) Why is this crashing? 2) What should I be doing differently if I want to load transparent images and apply color filters, overlay them on each other to create new bitmaps, etc? All of this works fine as long as all of my images have no background.

public class ThingHolder {

Thing[] things;

public ThingHolder() {
    things = new Thing[3];
    things[0] = new Thing();  // The first one works fine
    things[1] = new Thing();  // The second fails, see below
    ...
    // Note: It never gets far enough to draw the bitmap 
      // to a Canvas, that occurs much later
    ...
    canvas.drawBitmap(things[0].bmp, null, rect, things[0].paint);
    canvas.drawBitmap(things[1].bmp, null, rect, things[1].paint);
    }
}

public class Thing {

Bitmap bmp;
Paint paint;

public Thing() {
    bmp = getBmp(1);  // this always returns resource file circle.png
    paint = new Paint();
    paint.setColorFilter(new ColorMatrixColorFilter(redMatrix()));
    // RuntimeException occurs here if circle.png has a background color
// But it works fine if circle.png was saved in MS Paint, or in 
      // Gimp without the background color option checked
}

private float[] redMatrix() {
    float[] matrix = { 
            1, 0, 0, 0, 0, //red
            0, 0, 0, 0, 0, //green
            0, 0, 0, 0, 0, //blue
            0, 0, 0, 1, 0  //alpha
        };
    return matrix;
}
}

Edit 1: Here's the trace, in case it's helpful: DalvikVM[localhost:8611]
Thread [<1> main] (Suspended (exception RuntimeException))
ActivityThread.performLaunchActivity(ActivityThread$ActivityRecord, Intent) line: 2663
ActivityThread.handleLaunchActivity(ActivityThread$ActivityRecord, Intent) line: 2679
ActivityThread.access$2300(ActivityThread, ActivityThread$ActivityRecord, Intent) line: 125 ActivityThread$H.handleMessage(Message) line: 2033
ActivityThread$H(Handler).dispatchMessage(Message) line: 99 Looper.loop() line: 123 ActivityThread.main(String[]) line: 4627
Method.invokeNative(Object, Object[], Class, Class[], Class, int, boolean) line: not available [native method]
Method.invoke(Object, Object...) line: 521
ZygoteInit$MethodAndArgsCaller.run() line: 868
ZygoteInit.main(String[]) line: 626 NativeStart.main(String[]) line: not available [native method]

Edit 2: This occurred using a 2.2 target (specifically, android-x86-2.2-eeepc running in VirtualBox). When run against a 3.2 target, it looks like there are still some problems with Bitmap handling elsewhere, but it no longer throws a RuntimeException. So it would seem like maybe this is just a bug.

0

There are 0 best solutions below