Replace a specific color in the bitmap with transparency

I have a way to replace a pixel of the same color with transparency

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; } 

He is called like that

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

I have the same color in the png file where I want a transparent hole. The problem is that it only replaces part of the color with not all. See the screenshot https://docs.google.com/document/d/18aH43sFmsuuRu0QNfMTD1zek8sqWwH_pTauFofDZeIw/edit

+4
source share
2 answers

It looks like you have JPEG artifacts in the picture. Accurate color detection will only work if you save the image in a lossless format. PNG is a lossless format, but did you save the intermediate version of your image in JPEG format (or in another lossy format) after drawing a circle?

Also; just a hint: you don't need two loops, just loop through an array in one for a loop.

Edit: This new yellow color looks like it was caused by smoothing. Because of this, the edges of the circle are not the exact color you are looking for, and your code skips them. The only way around this is to turn off anti-aliasing when drawing a circle. Of course, this way you also wonโ€™t get a beautiful smooth edge for your transparent hole.

If you want this, you probably have to use a separate mask for the hole (JPEG for color and 8-bit PNG for transparency should be a pretty effective combination - oh, as far as I want, there was an image format that easily resolved this in web browsers)

+4
source

Very good, I needed it, and then I improved a bit, the code:

 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; } 
+2
source

Source: https://habr.com/ru/post/1382988/


All Articles