蜂窝硬件加速似乎无法与setColorFilter一同使用

5
这段代码使用位图的 alpha 通道绘制了一个带有透明度的单色形状。
Bitmap alphaMask = bitmap.extractAlpha();
Paint paint = new Paint();
int color = Color.GRAY;
...
paint.setColor(color);
paint.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.DST_IN));
...
canvas.drawBitmap(alphaMask, x, y, paint);

例如,它将会把左侧的位图绘制到画布上,就像右侧所显示的那样:

enter image description here

然而,当开启硬件加速时,它在Honeycomb(Android 3.0)上无法工作。无论如何,它都会将形状绘制为黑色。它忽略了颜色值。但是,在ICS(Android 4.0)上,即使开启硬件加速,它也能正常工作。
我知道一些API不支持硬件加速,如Romain Guy documented here所述,在What drawing operations are supported?下,但我似乎没有使用任何不支持的操作之一。
此外,听起来他说setColorFilter应该在at this post中工作。
我的代码中是否有某些在Honeycomb中不受支持的东西?有什么解决办法吗?在这种情况下,我很想保持硬件加速。
谢谢
2个回答

6

Android 3.0存在alpha8位图处理BUG。非常抱歉,这完全是我的错。但是这个问题在Android 4.0中已经得到修复。

有两种可能的解决方法: - 在您的视图上设置软件层类型 - 或创建自己的位图,并在其中呈现所需内容。然后,您可以在硬件加速画布上绘制此位图。


+1。非常好。感谢你的光临并让我们知道! :) - MrGomez
1
嘿,别担心,你们在Android方面已经做得很出色了,不需要道歉!无论如何,我最终采取了将绘图绘制到位图中,然后像你说的那样将位图绘制到硬件加速画布上的方法。对我来说很有效!谢谢。 - cottonBallPaws
@littleFluffyKitty,我很高兴一切都解决了。谢谢你,@RomainGuy! - MrGomez

4

我认为最好的答案来自Romain Guy。他说

然而,你所描述的应该可以正常工作。所有渐变都被支持,以及所有混合模式。请报告任何遇到的问题,并提供可重现的测试用例,我会把它们修复。

根据这个声明,你正在经历的行为是一个错误。这是那些情况之一,联系负责主要开发人员实际上是可以提供最好的技术解决方案。

不过,他确实发布了一个解决方法:

我检查了实现,硬件渲染器目前仅支持ComposeShader中不同类型的着色器。这意味着您可以使用渐变+位图,但不能使用两个位图或两个渐变。请注意,对于执行硬件不支持的操作的视图,您可以使用setLayerType(LAYER_TYPE_SOFTWARE,null)强制它们在软件中渲染。

或许他会在这里发帖,进一步启迪我们所有人。 他已经发了。 :)


谢谢提供这些信息。我尝试设置view.setLayerType(LAYER_TYPE_SOFTWARE, null),但onDraw()接收到的画布仍然是硬件加速的(canvas.isHardwareAccelerated),代码仍然产生错误的结果。似乎画布本身不能使用硬件加速。 - cottonBallPaws
有人知道如何让画布进行软件渲染吗? - cottonBallPaws
1
将图层类型设置为软件。如果您得到了一个硬件画布,可能是因为您在错误的视图上设置了该图层。 - Romain Guy
1
我在构造函数中设置了 view.setLayerType(LAYER_TYPE_SOFTWARE, null),并在 onDraw() 中记录 getLayerType() 以验证它。每次记录的值都是1 (LAYER_TYPE_SOFTWARE)。即使如此,Canvas仍然是 GLES20RecordingCanvas 的实例。我能够通过您在答案中提到的Bitmap路线解决这个问题。 - cottonBallPaws

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接