문제

I am having difficulties using the ColorMatrixColorFilter to modify the color pixels in a bitmap. If I use a bitmap from the local file system (a jpg), it works. However, if I use a bitmap created from a Buffer, nothing is drawn on the canvas.

In particular, I'm using the following code to create the ColorMatrix:

    float matrix[] = new float[] {
            0, 0, 1, 0, 0,
            0, 1, 0, 0, 0,
            1, 0, 0, 0, 0,
            0, 0, 0, 1, 0
    };
    rbSwap = new ColorMatrix(matrix);
    paint = new Paint(Paint.FILTER_BITMAP_FLAG);
    paint.setColorFilter(new ColorMatrixColorFilter(rbSwap));

The above is used to create a ColorMatrixColorFilter that is used to swap the red and blue colors.

If I create the bitmap using the following code, it works:

bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.picture);

If I create the bitmap using the following code, nothing is ever drawn to the canvas:

bitmap = Bitmap.createBitmap((int) width, (int) height,
            Bitmap.Config.ARGB_8888);

srcBuffer = ByteBuffer.wrap(data);
    srcBuffer.rewind();
    bitmap.copyPixelsFromBuffer(srcBuffer);

My onDraw() looks like the following:

public void onDraw(Canvas canvas) {
    canvas.drawBitmap(spicebmp, offsetX, offsetY, paint);
}

If I don't set the colorfilter, the bitmap renders on my canvas. If I set the colorfilter, it is simply a black screen - nothing appears to render. If I use the jpg bitmap instead of the one I am creating via the buffer, it draws with the red/blue swapped.

I changed the matrix to be the same as the identity matrix and the bitmap is rendered properly. If I change any single float in the matrix (like the 1s to .5s or 0), nothing is drawn.

I've also checked to make sure that the bitmap has enough "bytes" to represent the bitmap. bitmap.byteCount() == srcBuffer.limit() was true - so the bytes in my buffer were the same as what should be present for the width/height that I am passing in.

I put a try/catch for any exception during the onDraw as well as poured through the logcat output, but didn't see anything there. I poked around in the Android bitmap drawing code and saw the following:

// nothing to draw
if (fClip->isEmpty() ||
        bitmap.width() == 0 || bitmap.height() == 0 ||
        bitmap.getConfig() == SkBitmap::kNo_Config ||
        (origPaint.getAlpha() == 0 && origPaint.getXfermode() == NULL)) {
    return;
}

I don't have the ability to trace into the C++ code in the core so I can't tell if this is triggering. But I do know that my bitmap's width and height are both non-zero (they are 800 and 600) and I know that my bitmap was set on creation to be of type ARGV_8888 and the exact same paint object is used for both a jpg loaded from disk (the one that works) and for the one I create using the copyPixelsFromBuffer().

So I'm not sure what I am doing wrong. I presume it is some flag or property in the bitmap that is incompatible with colorFiltering, but it is just a simple ByteBuffer of the proper size of type ARGB_8888. And of course, the exact same code (paint object, etc) is used to set up the filter.

So is there something else I need to be doing with the Bitmap? With the ColorMatrix/Filter?

도움이 되었습니까?

해결책

As it turns out, my minsdkversion was set to version 10. When I added a targetsdkversion of 14, everything now works fine. Apparently, ColorMatrixColorFilter has different behavior/interface for older versions of Android (pre-Honeycomb).

In each of those older versions, the matrix values applied to the alpha channel always resulted in 0 if the alpha channel byte was 0. The fifth value in the matrix was not added into the formula.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top