本文介绍了按机器上查看启用的矩形覆盖带有硬件加速的孔的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个观点,做一些基本的绘图。此后,我要画有孔的矩形冲切使得previous绘图仅一个区域是可见的。我想与启用了我的观点的最佳性能硬件加速做到这一点。

I have a view which does some basic drawing. After this I want to draw a rectangle with a hole punched in so that only a region of the previous drawing is visible. And I'd like to do this with hardware acceleration enabled for my view for best performance.

目前我有两个的工作方法,但只当禁用硬件加速,另一种是太慢了。

Currently I have two methods that work, but only works when disabled hardware acceleration and the other is too slow.

方法1:SW加速(慢)

final int saveCount = canvas.save();

// Clip out a circle.
circle.reset();
circle.addCircle(cx, cy, radius, Path.Direction.CW);
circle.close();
canvas.clipPath(circle, Region.Op.DIFFERENCE);

// Draw the rectangle color.
canvas.drawColor(backColor);

canvas.restoreToCount(saveCount);

启用了视图硬件加速,因为canvas.clipPath不支持在此模式下(我知道我可以强制软件渲染,但我想避免这种情况)。

This does not work with hardware acceleration enabled for the view because 'canvas.clipPath' is not supported in this mode (I know i can force SW rendering, but I'd like to avoid that).

方法2:硬件加速(五慢)

// Create a new canvas.
final Bitmap b = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
final Canvas c = new Canvas(b);

// Draw the rectangle colour.
c.drawColor(backColor);

// Erase a circle.
c.drawCircle(cx, cy, radius, eraser);

// Draw the bitmap on our views  canvas.
canvas.drawBitmap(b, 0, 0, null);

在哪里橡皮创建为

Where eraser is created as

eraser = new Paint()
eraser.setColor(0xFFFFFFFF);
eraser.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));

这显然是缓慢的 - 视图的新位图尺寸创建的每个绘图调用

This is obviously slow -- a new Bitmap the size of the view is created every drawing call.

方法3:硬件加速(快,不会在某些设备上工作)

canvas.drawColor(backColor);
canvas.drawCircle(cx, cy, radius, eraser);

一样的硬件加速兼容的方法,但是不需要额外的画布。没有与本次重大问题 - 它的工作原理与软件渲染强制,但对的HTC One X(安卓4.0.4 - 并且可能是一些其他设备)至少与硬件渲染使得它离开圆全黑。这可能与 22361

方法4:硬件加速(可接受的,适用于所有设备)

按一月的建议改善方法2,我避免创造每个呼叫的位图的OnDraw ,而不是这样做的 onSizeChanged

As per Jan's suggestion for improving method 2, I avoided creating the bitmap in each call to onDraw, instead doing so in onSizeChanged:

if (w != oldw || h != oldh) {
    b = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
    c = new Canvas(b);
}

然后就是用这些在的OnDraw

if (overlayBitmap == null) {
   b = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
   c = new Canvas(b);
}
b.eraseColor(Color.TRANSPARENT);
c.drawColor(backColor);
c.drawCircle(cx, cy, radius, eraser);
canvas.drawBitmap(b, 0, 0, null);

的性能不如方法3,但比2好得多,略好于1。

The performance is not as good as method 3, but much better than 2 and slightly better than 1.

问题

我怎样才能达到同样的效果,但这样做与硬件加速兼容的方式(和设备上都能正常工作)?这增加了SW渲染性能的方法,也将是可接受的。

How can I achieve the same effect but do so in a manner compatible with HW acceleration (AND that works consistently on devices)? A method which increases the SW rendering performance would also be acceptable.

注:当四处移动一圈,我只是无效的区域 - 而不是整个画布 - 所以没有余地的性能提升有

NB: When moving the circle around I am just invalidating a region -- not the entire canvas -- so there's no room for a performance improvement there.

推荐答案

而不是每个重绘分配一个新的画布,你应该能一次分配,然后再用每个重画在画布上。

Instead of allocating a new canvas on each repaint, you should be able to allocate it once and then reuse the canvas on each repaint.

在初始化和调整大小:

Bitmap b = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);

在重绘:

b.eraseColor(Color.TRANSPARENT);
    // needed if backColor is not opaque; thanks @JosephEarl
c.drawColor(backColor);
c.drawCircle(cx, cy, radius, eraser);

canvas.drawBitmap(b, 0, 0, null);

这篇关于按机器上查看启用的矩形覆盖带有硬件加速的孔的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

06-20 05:48