2015-02-07 52 views
2

我在我的桌面上查看保存的位圖時,我幾乎看不到通過圖像文件的方格圖案注意到了這一點(這似乎是一個bug)。我做了一個簡單的實驗:Canvas.draw()在不透明的背景結果的透明形狀254阿爾法

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。正確的阿爾法是255。無論我正在繪製的形狀的alpha是什麼,我都會得到254。我假設這是一個舍入錯誤。有沒有其他人遇到過這個?這是預期的,如果是的話,爲什麼?如果沒有,有關如何避開它的任何想法?

回答

1

是的,看起來像是一個bug。

一種解決方法可以是使用另一Bitmap畫出半透明的形狀,然後使用drawBitmap方法繪製位圖。該其他位圖的背景是透明的,並且這種方式(顯然),形狀將被正確繪製。 (或者,如果你打算重用的位圖,您可以用透明填充它。)


示例代碼和輸出:

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:因爲這是一種變通方法矯枉過正,我們應該將此情況報告給谷歌。

+0

在此處打開問題:[link](https://bugs.chromium.org/p/skia/issues/detail?id=6804&q=transparent&colspec=ID%20Type%20Status%20Priority%20M%20Area%20Owner% 20Summary) – 2017-06-30 21:47:26