Android introduced BlendMode
s in API 29, which is a pretty easy way to apply a zero-saturation colour to a Paint
and use that to desaturate an image:
Paint paint = new Paint();
paint.setBlendMode(BlendMode.SATURATION);
// just for illustration - it's black by default anyway (zero saturation)
paint.setColor(Color.GRAY);
canvas.drawRect(rect, paint);

Unfortunately, as far as I can tell, if you want compatibility with anything before API 29 you're out of luck - there's a bunch of BlendModeCompat
classes but they fall back to PorterDuff blending on older APIs, and that can't do saturation, so it straight up won't work and you'll get a compatibility warning even if you use BlendModeCompat.SATURATION
.
So instead, you can set a ColorMatrixColorFilter
on your Paint
, using a ColorMatrix
with its saturation set to zero. This isn't a blending mode, it just affects the look of the thing you're drawing - so you basically have to redraw part of the bitmap using this paint:
ColorMatrix matrix = new ColorMatrix();
matrix.setSaturation(0f);
paint.setColorFilter(new ColorMatrixColorFilter(matrix));
// I don't know how you're getting your bitmaps, but here's an example of pulling one
// from an ImageView, drawing on it, and setting it on the ImageView again
Bitmap bitmap = imageView.drawable.toBitmap();
Canvas canvas = new Canvas(bitmap);
// using the same rect so we're copying and pasting the exact same region
canvas.drawBitmap(bitmap, rect, rect, paint);
imageView.setImageBitmap(bitmap);

I don't know if there are any better options available (there are definitely some more complicated ones!) but hopefully that gives you some ideas about how you can adapt it to what you're doing. Also you'll need another Paint
to draw that red border around the rect afterwards!