用透明度替换位图中的特定颜色

4
我有一种方法可以用透明度替换一种颜色的像素。
public Bitmap createTransparentBitmapFromBitmap(Bitmap bitmap,
          int replaceThisColor) {
        if (bitmap != null) {
          int picw = bitmap.getWidth(); 
          int pich = bitmap.getHeight();
          int[] pix = new int[picw * pich];
          bitmap.getPixels(pix, 0, picw, 0, 0, picw, pich);

          int sr = (replaceThisColor >> 16) & 0xff;
          int sg = (replaceThisColor >> 8) & 0xff;
          int sb = replaceThisColor & 0xff;

          for (int y = 0; y < pich; y++) {   
            for (int x = 0; x < picw; x++) {
              int index = y * picw + x;
            /*  int r = (pix[index] >> 16) & 0xff;
              int g = (pix[index] >> 8) & 0xff;
              int b = pix[index] & 0xff;*/

              if (pix[index] == replaceThisColor) {

                if(x<topLeftHole.x) topLeftHole.x = x;  
                if(y<topLeftHole.y) topLeftHole.y = y;
                if(x>bottomRightHole.x) bottomRightHole.x = x;
                if(y>bottomRightHole.y)bottomRightHole.y = y;

                pix[index] = Color.TRANSPARENT;   
              } else {
                //break;
              }
            }
          }

          Bitmap bm = Bitmap.createBitmap(pix, picw, pich,
              Bitmap.Config.ARGB_8888);  

          return bm;
        }
        return null;
      }

它被称为这样

backgroundBitmap = createTransparentBitmapFromBitmap(backgroundBitmap , Color.argb(255,255,255, 0));

我有一张PNG文件,其中有一个我想要透明区域的颜色。问题是它只替换部分颜色而不是全部。请参见截图https://docs.google.com/document/d/18aH43sFmsuuRu0QNfMTD1zek8sqWwH_pTauFofDZeIw/edit

那个链接给了我一个没有标题的文档。你确定你已经正确设置了共享和其他相关内容吗? - Matti Virkkunen
我刚刚编辑了一下,现在应该没问题了。 - tsukimi
2个回答

4
看起来你的图片有JPEG伪像。只有在使用无损格式保存图片时,检测确切的颜色才能真正奏效。PNG是无损格式,但你是否在画圆后将它的中间版本另存为JPEG(或其他有损格式)了?
此外,小建议:你并不需要两个循环,只需在一个for循环中遍历数组。
编辑:这个新黄色看起来是由于反锯齿造成的。因此,圆的边缘不是你要找的确切颜色,你的代码错过了它们。唯一的解决方法是在画圆时关闭反锯齿。当然,这样做也就意味着你将失去一个美丽的反锯齿透明边缘。
如果你想要得到那个边缘,你可能需要为洞留下一个单独的掩码(一种JPEG用于颜色和一个8位PNG用于透明度应该是一种相当有效的组合——我多么希望有一种图像格式可以在Web浏览器中轻松实现这一点)。

Matti,感谢您的回复。该图像是 .jpg 格式,我刚刚将其保存为 .png 格式,透明度好多了。它仍然有一些黄色显示,我已更新了 Google 文档,最后一张图片。有没有办法改进,使得没有或者更少的黄色显示出来? - tsukimi
也许我可以对那个色彩容忍度为+-10或者其他数值。我并不是很理解你的遮罩建议,可以再详细说明一下吗?平面设计不是我的强项。 - tsukimi
@tsukimi:这样会增加它在其他地方找到足够黄色的杂色像素的可能性。 - Matti Virkkunen

2
非常好,我需要这个,然后在使用的过程中我稍微改进了一下代码:
public static Bitmap repleceIntervalColor(Bitmap bitmap,int redStart,int redEnd,int greenStart, int greenEnd,int blueStart, int blueEnd,int colorNew) {
    if (bitmap != null) {
        int picw = bitmap.getWidth();
        int pich = bitmap.getHeight();
        int[] pix = new int[picw * pich];
        bitmap.getPixels(pix, 0, picw, 0, 0, picw, pich);
        for (int y = 0; y < pich; y++) {
            for (int x = 0; x < picw; x++) {
                int index = y * picw + x;
                    if (
                        ((Color.red(pix[index]) >= redStart)&&(Color.red(pix[index]) <= redEnd))&&
                        ((Color.green(pix[index]) >= greenStart)&&(Color.green(pix[index]) <= greenEnd))&&
                        ((Color.blue(pix[index]) >= blueStart)&&(Color.blue(pix[index]) <= blueEnd))
                    ){
                        pix[index] = colorNew;
                    }
                }
            }
        Bitmap bm = Bitmap.createBitmap(pix, picw, pich,Bitmap.Config.ARGB_8888);
        return bm;
    }
    return null;
}

1
这是最佳解决方案,可快速删除所选颜色。非常感谢。 - deepti

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