0

How can I achieve a rectangle having black and white transparent background. I want something like this https://i.stack.imgur.com/krsPI.jpg

Please help me to achieve same result on Android SDK. this is my function which creates rectangle using canvas.

private void drawRectangle() {
    Bitmap bitmap = Bitmap.createBitmap(500, 500, Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    Paint paint = new Paint();
    paint.setStyle(Paint.Style.FILL);
    paint.setColor(Color.parseColor("#D20E0F02"));
    canvas.drawRect(400, 180, 80, 350, paint);
}
Vickey
  • 1
  • 2
  • not by simply drawing. You probably have to read the pixels underneath, and edit them. Where did the pixels come from, are they from your app? you show the canvas painting on a bitmap, is it your bitmap, is the jellybean picture already on it? – user253751 Jul 22 '22 at 18:32
  • 1
    Follow this https://stackoverflow.com/questions/3373860/convert-a-bitmap-to-grayscale-in-android – Gobu CSG Jul 22 '22 at 19:41

1 Answers1

0

Android introduced BlendModes 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);

An image with a desaturated square in the middle


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

Another bitmap with a desaturated area in the middle

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!

cactustictacs
  • 17,935
  • 2
  • 14
  • 25
  • getting grayscale rectangle but background is not transparent. please look https://drive.google.com/file/d/1pDUmVzxwJy8DHvxvCbpr-z-CSHrEyJlL/view?usp=sharing – Vickey Jul 23 '22 at 05:45
  • @Vickey are you using `drawBitmap` for the second approach? The first example uses a blending mode, so you can just draw a grey rectangle and it'll blend with the background (applying its saturation to the background pixels). The second example doesn't use blending (it's not available on lower APIs) so you have redraw part of the bitmap onto itself using a desaturated colour filter – cactustictacs Jul 23 '22 at 18:41
  • 1
    no I'm using drawRect. can you provide me a complete code for this? – Vickey Jul 24 '22 at 10:36
  • @Vickey I did in the answer! The second example. Make a Canvas for your background bitmap, then call `drawBitmap` on it, passing in the background bitmap again, the same `Rect` for the source and destination, and the paint with the colour filter set on it. I don't know how you're drawing the background in the first place so I can't be any more specific than that, but my code example shows you how to grab the bitmap from an `ImageView` and put it back once you're done drawing on it, if you need to do that – cactustictacs Jul 24 '22 at 16:17