-1

I've been searching the internet for changing colour or overlaying a specific part of a bitmap. I've a square bitmap and I want to change the colour in a matrix pattern that is in equal 9 blocks which can be understood from the following image. (Cyan colour line here is for demonstration only) enter image description here

I've read about boundary fill algorithm in College but here for java, I came to know that it is too bulky to perform such an operation for 9 specific parts. And I don't know how to use Paint with Canvas for such a square scenario.

So is there a method or something which can help me figure out how to paint a specific square by providing the size or location without performing a huge task on UI.

Here's what I need to achieve:

enter image description here

I can change the color, location,size by myself if there's something which can help me out. Also, as there is white background, is there a way to not paint the background or do I have to use PNG?

Update:

I'm successfully able to divide the image in 9 equal parts using following code but PorterDuffColorFilter is not working as expected.

Code:

public void splitBitmap(Bitmap bitmap) {
        int width, height;
        // Divide the original bitmap width by the desired vertical column count
        width = bitmap.getWidth() / 3;
        // Divide the original bitmap height by the desired horizontal row count
        height = bitmap.getHeight() / 3;
        // Loop the array and create bitmaps for each coordinate
        for (int x = 0; x < 3; ++x) {
            for (int y = 0; y < 3; ++y) {
                // Create the sliced bitmap
                smallimages.add(Bitmap.createBitmap(bitmap, x * width, y * height, width, height));
            }
        }
        Intent intent = new Intent(this, MainActivity.class);
        startActivity(intent);
    }

The above code provides 9 bitmaps which then set to a GridLayout. But No mode of PorterDuffColorFilter is useful. Either the images remain original or is painted completely. I've tried every one of the modes available and none worked.

Lalit Fauzdar
  • 5,953
  • 2
  • 26
  • 50
Hardik sharma
  • 313
  • 2
  • 15

1 Answers1

0

I've done something similar to this so after changing my code a bit, I think this is what you want:

Assuming that you don't have PNG,

First, remove the white background from your image Source:
Setting the white color as Transparent, you can use any color you want.

private static final int[] FROM_COLOR = new int[]{255, 255, 255};
private static final int THRESHOLD = 3;

public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.test_colors);

    ImageView iv = (ImageView) findViewById(R.id.img);
    Drawable d = getResources().getDrawable(RES);
    iv.setImageDrawable(adjust(d));
}

private Drawable adjust(Drawable d)
{
    int to = Color.TRANSPARENT;

    //Need to copy to ensure that the bitmap is mutable.
    Bitmap src = ((BitmapDrawable) d).getBitmap();
    Bitmap bitmap = src.copy(Bitmap.Config.ARGB_8888, true);
    for(int x = 0;x < bitmap.getWidth();x++)
        for(int y = 0;y < bitmap.getHeight();y++)
            if(match(bitmap.getPixel(x, y))) 
                bitmap.setPixel(x, y, to);

    return new BitmapDrawable(bitmap);
}

private boolean match(int pixel)
{
    //There may be a better way to match, but I wanted to do a comparison ignoring
    //transparency, so I couldn't just do a direct integer compare.
    return Math.abs(Color.red(pixel) - FROM_COLOR[0]) < THRESHOLD &&
        Math.abs(Color.green(pixel) - FROM_COLOR[1]) < THRESHOLD &&
        Math.abs(Color.blue(pixel) - FROM_COLOR[2]) < THRESHOLD;
}

Above code will change the color to transparent and below code will split the bitmap into 9 same size bitmaps:

public void splitBitmap(Bitmap bitmap) {
        ArrayList<Bitmap> smallimages = new ArrayList<>(9);
        int width, height;
        // Divide the original bitmap width by the desired vertical column count
        width = bitmap.getWidth() / 3;
        // Divide the original bitmap height by the desired horizontal row count
        height = bitmap.getHeight() / 3;
        // Loop the array and create bitmaps for each coordinate
        for (int x = 0; x < 3; ++x) {
            for (int y = 0; y < 3; ++y) {
                // Create the sliced bitmap
                smallimages.add(Bitmap.createBitmap(bitmap, x * width, y * height, width, height));
            }
        }
    }

At last, you can use PorterDuffColorFilter on every bitmap:

    imageView.setImageDrawable(arrayList.get(0));
    imageView.setColorFilter(Color.BLACK, PorterDuff.Mode.SRC_ATOP);

There can be problems as it works for me and might not for you but this is the way you can achieve your needed result. If any problem persists, I can help.

Lalit Fauzdar
  • 5,953
  • 2
  • 26
  • 50
  • Although, I had to change `Drawable` to `Bitmap` as your `splitBitmap` needs `Bitmap` and `adjust` returns a Drawable but your code helped me. Thanks +1. – Hardik sharma Mar 29 '18 at 09:27