Canvas.draw()在不透明背景上的透明形状导致254 alpha

时间:2015-02-07 04:45:11

标签: android android-canvas

我在桌面上查看已保存的位图时发现了这个(看起来像是一个错误),我几乎看不到图像文件中的方格图案。我做了一个简单的实验:

Bitmap bitmap = new Bitmap(300, 200, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
Paint  paint  = new Paint();
paint.setColor(Color.argb(150, 0, 255, 0));
canvas.drawColor(Color.RED);
canvas.drawRect(20, 20, 280, 180, paint);
Log.d("alpha-bug", "Alpha at 30, 30 is "
  + Color.alpha(bitmap.getPixel(30, 30))
);

验证。以上日志Alpha at 30, 30 is 254。正确的alpha是255。无论我绘制的形状的alpha是什么,我都会得到254。我假设这是一个舍入错误。还有其他人遇到过这个吗?这是预期的,如果是这样,为什么?如果不是,关于如何绕过它的任何想法?

1 个答案:

答案 0 :(得分:1)

是的,对我来说似乎是个错误。

解决方法可以使用其他Bitmap 绘制半透明形状,然后使用drawBitmap方法绘制该位图 。其他位图的背景是透明的,这样(显然),将正确绘制形状。 (或者,如果您正在重复使用位图,则可以使用drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR)将其填充为透明。)

示例代码和输出:

Bitmap test = Bitmap.createBitmap(250, 190, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(test);
{ // draw opaque background
    Paint p = new Paint();
    p.setARGB(255, 0, 0, 0);
    c.drawPaint(p);
}
Paint circlePaint = new Paint();
circlePaint.setARGB(128, 255, 255, 255);
Bitmap b;
c.drawText("drawCircle", 30, 40, circlePaint);
c.drawText("drawBitmap", 140, 40, circlePaint);
{ // draw a circle into a temporary bitmap as workaround
    b = MipMap.allocateBitmapSafely(100, 100);
    Canvas ca = new Canvas(b);
    ca.drawCircle(50, 50, 50, circlePaint);
    System.out.println("drawCircle (in temporary bitmap) color: " + Integer.toHexString(b.getPixel(50, 50)));
}
{ // draw circle with circle-drawing method
    c.drawCircle(70, 100, 50, circlePaint);
    System.out.println("drawCircle color: " + Integer.toHexString(test.getPixel(70, 100)));
}
{ // draw circle from the saved bitmap with bitmap-drawing method
    c.drawBitmap(b, 130, 50, null);
    System.out.println("drawBitmap color: " + Integer.toHexString(test.getPixel(170, 100)));
}
String filename = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "test.png";
FileOutputStream out = null;
try {
    out = new FileOutputStream(filename);
    test.compress(Bitmap.CompressFormat.PNG, 90, out);
} catch (Exception e) {
} finally {
    try {
        out.close();
    } catch (IOException e) {
    }
}

控制台输出:

drawCircle (in temporary bitmap) color: 80ffffff drawCircle color: fe818181 drawBitmap color: ff808080

Example output image

在图像中,左圆的颜色是(254,129,129,129),右边的颜色是(255,128,128,128)。所以不仅左边是alpha 254而不是255,R,G和B值也都是1。

P.S。:我们应该向Google报告此问题,因为这对解决方法来说太过分了。