使用alpha通道绘制位图:请告知...(一些解决方案和速度问题)

时间:2012-01-12 13:20:28

标签: android performance bitmap rgb alpha

我有相当多的小位图(100 +,大小约40x40),每个都有一些不透明和一些透明的部分,我需要根据这些区域绘制它们。

位图采用ARGB格式,888(rgb)加256bit alpha通道,标准格式与PNG格式相同。

我发现绘制它们的唯一(工作)方式是以下方法:

  1. 创建位图(ARGB_8888)
  2. 使用原始数据填充位图
  3. 从位图中提取alpha图层
  4. 基于原始位图
  5. 创建BitmapShader(RGB_565)
  6. 为使用创建的着色器的位图创建绘画

  7. 然后使用带有特殊BitmapShader的绘画绘制alpha蒙版。

  8. 初始化代码当然只运行一次:

    void initializeTile( int t ){
    // Allocate the bitmap:
    Bitmap original_data = Bitmap.createBitmap( tile_w, tile_h, Bitmap.Config.ARGB_8888);
    // Fill with raw data (this is actually native C++ code):
    populateBitmap( original_data );
    // Get the alpha mask:
    tile_mask[ t ] = original_data.extractAlpha();
    // Create the bitmap shader:
    tile_data = original_data.copy( Bitmap.Config.RGB_565, false);
    // Create the shader:
    BitmapShader shader = new BitmapShader(tile_data, CLAMP, CLAMP);
    
    // Create the paint:
    tile_paint[ t ] = new Paint();
    tile_paint[ t ].setDither(true);
    tile_paint[ t ].setAntiAlias(true);
    tile_paint[ t ].setFilterBitmap(true);
    tile_paint[ t ].setShader( shader );
    }
    

    油漆代码是最简单的,它在主绘制循环中:

    void paintTile(t){
    canvas.drawBitmap( tile_mask[ t ],  tile_x[ t], tile_y[ t], tile_paint[ t] );
    }
    

    现在,在像Ideos(Android 2.2)这样的手机上,它运行顺畅而且很好,但在其他手机上,如高端的三星Galaxy SII(Android 2.3),它的蹩脚和缓慢。这对我来说没什么意义......

    那么,您如何看待这种方法?是否有更好,更快的方法来实现相同的结果?

    而且,为什么你认为在现代,快速的硬件上这么慢?有没有办法改善它?

1 个答案:

答案 0 :(得分:4)

好的,经过一些工作,我发现了一个更好的解决方案。我不能回答我自己的问题,所以如果你比我更了解,请做。

但是,如果有更多人需要这个,我发布我的新解决方案,虽然有点复杂,但速度要快得多。关键的想法是仅在初始化期间使用着色器方法而不是绘画。

为此,我创建了一个新的位图,它将使用着色器方法包含“剪切”位图(清除所有透明区域),然后在绘图代码中绘制没有任何着色器的剪切位图。

void initializeTile( int t ){
// Allocate the bitmap:
Bitmap original_data = Bitmap.createBitmap( tile_w, tile_h, Bitmap.Config.ARGB_8888);
// Fill with raw data (this is actually native C++ code):
populateBitmap( original_data );

// Now make a new bitmap to be clipped:
Bitmap clipped_data = Bitmap.createBitmap( tile_w, tile_h, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(clipped_data);
Paint clip_paint = new Paint();
clip_paint.setDither(true);
clip_paint.setAntiAlias(true);
clip_paint.setFilterBitmap(true);
clip_paint.setShader( new BitmapShader(original_data, CLAMP, CLAMP));
// Paint the clipped bitmap:
canvas.drawBitmap( tile_mask[ t ], 0, 0, clip_paint );
//Use the clipped bitmap as original bitmap:
tile_data[ t ] = clipped_data;
}

还有绘图代码:

void paintTile(t){
canvas.drawBitmap( tile_data[ t ],  tile_x[ t], tile_y[ t], null );
}

总的来说,这要快得多。 我还不清楚为什么Android不会在没有这些混乱的情况下正确地绘制我的alpha通道位图!