Android 使用ColorMatrixColorFilter时,画布不绘制位图
我在使用ColorMatrixColorFilter修改位图中的颜色像素时遇到困难。如果我使用本地文件系统jpg中的位图,它就可以工作。但是,如果使用从缓冲区创建的位图,则画布上不会绘制任何内容 特别是,我使用以下代码创建ColorMatrix:Android 使用ColorMatrixColorFilter时,画布不绘制位图,android,bitmap,android-canvas,colormatrix,colormatrixfilter,Android,Bitmap,Android Canvas,Colormatrix,Colormatrixfilter,我在使用ColorMatrixColorFilter修改位图中的颜色像素时遇到困难。如果我使用本地文件系统jpg中的位图,它就可以工作。但是,如果使用从缓冲区创建的位图,则画布上不会绘制任何内容 特别是,我使用以下代码创建ColorMatrix: float matrix[] = new float[] { 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0,
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));
以上内容用于创建用于交换红色和蓝色的ColorMatrixColorFilter
如果我使用以下代码创建位图,它可以工作:
bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.picture);
如果使用以下代码创建位图,则不会在画布上绘制任何内容:
bitmap = Bitmap.createBitmap((int) width, (int) height,
Bitmap.Config.ARGB_8888);
srcBuffer = ByteBuffer.wrap(data);
srcBuffer.rewind();
bitmap.copyPixelsFromBuffer(srcBuffer);
我的onDraw如下所示:
public void onDraw(Canvas canvas) {
canvas.drawBitmap(spicebmp, offsetX, offsetY, paint);
}
// nothing to draw
if (fClip->isEmpty() ||
bitmap.width() == 0 || bitmap.height() == 0 ||
bitmap.getConfig() == SkBitmap::kNo_Config ||
(origPaint.getAlpha() == 0 && origPaint.getXfermode() == NULL)) {
return;
}
如果不设置颜色过滤器,位图将在画布上渲染。如果我设置了颜色过滤器,它只是一个黑屏——没有任何东西可以渲染。如果我使用jpg位图,而不是通过缓冲区创建的位图,它将以红色/蓝色交换进行绘制
我将矩阵更改为与标识矩阵相同,位图被正确渲染。如果我将矩阵中的任何单个浮点数(如1)更改为.5s或0,则不会绘制任何内容
我还检查了位图是否有足够的字节来表示位图。bitmap.byteCount==srcBuffer.limit为true-因此我的缓冲区中的字节与我要传递的宽度/高度应显示的字节相同
在onDraw期间,我对任何异常都进行了try/catch,并对logcat输出进行了检查,但没有看到任何异常。我在Android位图绘图代码中浏览了一下,看到了以下内容:
public void onDraw(Canvas canvas) {
canvas.drawBitmap(spicebmp, offsetX, offsetY, paint);
}
// nothing to draw
if (fClip->isEmpty() ||
bitmap.width() == 0 || bitmap.height() == 0 ||
bitmap.getConfig() == SkBitmap::kNo_Config ||
(origPaint.getAlpha() == 0 && origPaint.getXfermode() == NULL)) {
return;
}
<>我没有能力跟踪内核中的C++代码,所以我无法判断这是否触发。但是我知道我的位图的宽度和高度都是非零的,它们分别是800和600,我知道我的位图在创建时被设置为ARGV_8888类型,从磁盘加载的jpg和使用copyPixelsFromBuffer创建的jpg都使用了完全相同的paint对象
所以我不确定我做错了什么。我假定位图中的某个标志或属性与颜色过滤不兼容,但它只是一个ARGB_8888类型的大小合适的简单ByteBuffer。当然,使用完全相同的代码绘制对象等来设置过滤器
那么我还需要对位图做些什么吗?使用颜色矩阵/过滤器 事实证明,我的minsdkversion设置为Version10。当我添加了一个targetsdkversion为14时,一切都正常了。显然,ColorMatrixColorFilter对于旧版本的Android pre Honeycomb具有不同的行为/界面
在这些旧版本中,如果alpha通道字节为0,则应用于alpha通道的矩阵值始终为0。矩阵中的第五个值没有添加到公式中。我已经缩小了问题的范围。我发现alpha通道字节总是设置为0。我的位图是xRGB格式,而不是ARGB格式。当我在没有颜色矩阵的情况下绘制时,Android似乎忽略了alpha字节。但是,当我使用ColorMatrixColorFilter渲染它时,它将Alpha字节设置为0,因此只渲染黑色。我更改了ColorMatrix,使最后五个浮点值为:0、0、0、0、255,期望该矩阵始终为alpha通道生成255。如果alpha字节为0,则A'=pR+qG+rB+sA+t不起作用。