使位图中特定颜色透明化。

4

我有一个Android应用程序,可以在另一张图片上显示一张图片,使第二张图片的白色透明。为了实现这个目的,我使用了两个ImageView,原始图像被叠加为bitmap1,需要透明化的图像被叠加为bitmap2。当我运行时,setPixel方法会出现一些异常。

这是我的代码:

Bitmap bitmap2 = null;
int width = imViewOverLay.getWidth();
int height = imViewOverLay.getHeight();
for(int x = 0; x < width; x++)
{
    for(int y = 0; y < height; y++)
    {
        if(bitMap1.getPixel(x, y) == Color.WHITE)
        {
            bitmap2.setPixel(x, y, Color.TRANSPARENT);
        }
        else
        {
            bitmap2.setPixel(x, y, bitMap1.getPixel(x, y));
        }
    }
}

imViewOverLay 是覆盖图像的 ImageView。你有什么想法,以上代码可能出了什么问题吗?


代码如下: Bitmap bitmap2 = null; int width = imViewOverLay.getWidth(); int height = imViewOverLay.getHeight(); for(int x=0;x<width;x++){ for(int y=0;y<height;y++){ if(bitMap1.getPixel(x, y) == Color.WHITE){ bitmap2.setPixel(x, y, Color.TRANSPARENT); }else{ bitmap2.setPixel(x, y, bitMap1.getPixel(x, y)); } } } - asifkt
尝试编辑您自己的帖子,将代码添加到问题正文中... - Frosty840
1
你得到了什么异常?除了示例中实际上没有创建“bitmap2”之外。 - ChrisF
2个回答

2
我认为您需要使其可变。以下是相关的IT技术链接:加载资源到可变位图。我已经完成了这个任务。
 BitmapFactory.Options bitopt=new BitmapFactory.Options();

 bitopt.inMutable=true;

 mSnareBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.snare, bitopt);

同时,我发现我需要将alpha设置为小于255的值,以便使用透明背景渲染图像。

 mPaint.setAlpha(250);
 canvas.drawBitmap(mSnareBitmap, 0, 30, mPaint);

顺便提一下,使用白色作为透明颜色并不是一个好主意,因为在不透明对象的边缘会出现锯齿问题。我使用绿色,因为我的叠加图像中没有任何绿色(就像电影中的绿幕),然后我可以在循环内部删除绿色并根据绿色值的相反数设置 alpha 值。

private void loadBitmapAndSetAlpha(int evtype, int id) {

        BitmapFactory.Options bitopt=new BitmapFactory.Options();
        bitopt.inMutable=true;
        mOverlayBitmap[evtype] = BitmapFactory.decodeResource(getResources(), id, bitopt);
        Bitmap bm = mOverlayBitmap[evtype];

        int width = bm.getWidth();
        int height = bm.getHeight();
        for(int x = 0; x < width; x++)
        {
            for(int y = 0; y < height; y++)
            {
                int argb = bm.getPixel(x, y);
                int green = (argb&0x0000ff00)>>8;
                if(green>0)
                {
                    int a = green;
                    a = (~green)&0xff;
                    argb &= 0x000000ff; // save only blue
                    argb |= a;      // put alpha back in
                    bm.setPixel(x, y, argb);
                }
            }
        }

    }

2
最明显的错误是你没有创建bitmap2 - 当然,除非你没有发布所有的代码。
你声明并将其设置为null,但在尝试调用bitmap2.setPixel之前没有做任何其他事情。

朋友们,我解决了这个问题。移除了bitmap2并将bitmap1设置为可变的。请问有没有什么方法可以加快循环操作?在我的应用程序中,它需要很长时间。 - asifkt
当我显示上面的图像时,它只显示第二个(bitmap1); 我需要它显示在另一个位图(bitmap3)上。 请有人给我一些提示。 我正在使用ImageView来显示图像。 - asifkt
@asifkt - 必要时,您必须循环遍历图像中的每个像素,如果您有一个大图像,这将需要一些时间。要么减小图像的大小,要么使用带有颜色调色板的图像,这样您就可以只更改调色板中的单个值。 - ChrisF
谢谢Chrisf,你能帮我在另一个位图上显示一个位图吗?如上所述,第二个要显示在另一个图像上的图像对于特定颜色是透明的。 - asifkt
asifkt - 对于Android显示管道,我不熟悉,恐怕无法回答。 - ChrisF
令我惊讶的是,Android不能使用任意颜色值绘制简单的透明位图!如果需要在运行时更改透明度颜色,则物理更改颜色或Alpha通道不是正确的方法。也许Google可以向画布类添加一个drawTransparentBitmap(bitmap,x,y,transpencyColor)类型的方法?Windows、directFB和我遇到的所有其他2D图形库都具有此功能。如果我错过了什么,请回复。谢谢。 - Batdude

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