I want to colorize a bitmap into different colors.
Thanks to this SE question i am able to tint my it into different colors when i draw it on my canvas.
Paint p = new Paint(Color.RED);
ColorFilter filter = new LightingColorFilter(Color.RED, 1);
p.setColorFilter(filter);
But this seems to not work with Color.WHITE (maybe because my bitmap is colorized in only 1 color).
I want to have a white shape of the original bitmap (only transparent + white)
Ok. I reply here for people who might face this problem.
In order to keep the shape of a bitmap, and colorize it you need to use a PorterDuffColorFilter instead of the LightingColorFilter i used initially.
filter = new PorterDuffColorFilter(Color.WHITE, PorterDuff.Mode.SRC_ATOP);
mPaint.setColorFilter(filter);
The second parameter is a PorterDuff.Mode, you can find the complete list here
Related
I have a question. I'm trying to make a simple file manager, and when the user clicks on an item, that item is supposed to be tinted to look more orangeish (or any other color I specify). I was looking at the Paint's .setColorFilter(ColorFilter filter) method, and I wanted to use it to set the color I want the image to be tinted in and then later call drawBitmap(imagepath, x, y, p <--my Paint class with a color filter) method to display the Bitmap with a different color. The problem is that I have looked at the ColorFilter class (the one I'm supposed to pass to setColorFilter()) and it has an empty constructor, and only one method, which doesn't at all do what the class's name suggests it does.
Can someone give me some directions?
Thanks in advance.
Links:
Paint,
ColorFilter
Here it is:
Paint p = new Paint();
p.setColorFilter(new PorterDuffColorFilter(Color.parseColor("#B3B3B3"), PorterDuff.Mode.DARKEN));
Just put the hex color value for the color you want and then select a PorterDuff mode.
Have fun!
I am using following code to apply font color when user click on perticular color like RED.
mPaint.setColor(getResources().getColor(R.color.color2));
And color2 in color.xml file is
<color name="color2">#FF3C00</color>
Now I am facing problem while applying following color.
I using canvas to draw paint on touching it in my application and i want to draw something like attached screen on canvas. I am able to draw it but It looks like solid color (I mean full circle but not dot dot inside)
Please help me to find this.
You can use BitmapShader for achieve that..
Here is sample code.. Try this code, I hope it will work..
Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.shader);
//Initialize the BitmapShader with the Bitmap object and set the texture tile mode
BitmapShader mBitmapShader = new BitmapShader(bitmap, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
fillPaint.setStyle(Paint.Style.FILL);
//Assign the 'fillBMPshader' to this paint
fillPaint.setShader(mBitmapShader);
//Draw the fill of any shape you want, using the paint object.
canvas.drawCircle(posX, posY, 100, fillPaint);
I have an 8x8 Image. (bitmap - can be changed)
What I want to do is be able to draw a shape, given a Path and Paint object onto my SurfaceView.
At the moment all I can do is fill the shape with solid colour. How can I draw it with a pattern.
In the image you can see the brush pattern (The cross). It can be anything from a cross to a donut or an elf.
How would I go about drawing this pattern background.
I also eventually want to apply colours to it.
So far, my theory is to create a clip area of the shape, and tile the bitmaps until area is covered, but this is extreme overkill in processing. Nor sound ideal.
In terms of colouring, I can edit the brushes to be alpha, fill the same with background colour, then draw the images on top. The real issue it the tiling of such patterns.
Ive found a few questions of a similar nature, all unanswered, and/or not applicable to my situation. (use of xmls on views etc)
Did you checked this blog. Its using BitmapShader
Example:
//Initialize the bitmap object by loading an image from the resources folder
fillBMP = BitmapFactory.decodeResource(m_context.getResources(), R.drawable.cross);
//Initialize the BitmapShader with the Bitmap object and set the texture tile mode
fillBMPshader = new BitmapShader(fillBMP, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
fillPaint.setStyle(Paint.Style.FILL);
//Assign the 'fillBMPshader' to this paint
fillPaint.setShader(fillBMPshader);
//Draw the fill of any shape you want, using the paint object.
canvas.drawCircle(posX, posY, 100, fillPaint);
I don't want to use a state selector. I want to write generic code to apply a filter to a text color, no matter what the original color might be.
This is actually part of tinting buttons when pressed. I've learned that I can tint an ImageButton easily:
imageButton.setColorFilter(Color.argb(150, 155, 155, 155));
For a Button, I can tint the background image:
button.getBackground().setColorFilter(0xFFFF0000, PorterDuff.Mode.MULTIPLY);
However, I'm having trouble figuring out how to tint the color value for the text of the Button. Any ideas? Is there some method somewhere so I can apply a PorterDuff tint to an arbitrary color value, so I can set the new value as the tet color?
I spent hours studying documentation and forums and can find absolutely no direct way to apply a PorterDuff filter to text or an arbitrary (int) color value; everything seems to relate to images.
My workaround is ugly, but the only solution I have found:
int normalTextColor = Color.argb(0, 155, 155, 155);
Bitmap bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); //make a 1-pixel Bitmap
Canvas canvas = new Canvas(bitmap);
canvas.drawColor(normalTextColor); //color we want to apply filter to
canvas.drawColor(pressedFilterColor, mode); //apply filter
int pressedTextColor = bitmap.getPixel(0, 0);
Presto--now you can use setColor() or setTextColor() with the new pressedTextColor on your TextView, Button, etc.
I would love to hear of an alternative that doesn't involve drawing a one-pixel Bitmap, as that seems rather ridiculous--but this does get the job done.
I am creating bitmap, next i am drawing second solid color bitmap on top of it.
And now i want to change first bitmap, so solid color that i drawed on it will be transparent.
Or simply, i want to remove all pixels of one color from bitmap.
I havie tried every colorfilter, and xfermode with no luck, is there any other possibility to remove color other that doing it pixel by pixel?
This works for removing a certain color from a bitmap. The main part is the use of AvoidXfermode. It should also work if trying to change one color to another color.
I should add that this answers the question title of removing a color from a bitmap. The specific question is probably better solved using PorterDuff Xfermode like the OP said.
// start with a Bitmap bmp
// make a mutable copy and a canvas from this mutable bitmap
Bitmap mb = bmp.copy(Bitmap.Config.ARGB_8888, true);
Canvas c = new Canvas(mb);
// get the int for the colour which needs to be removed
Paint p = new Paint();
p.setARGB(255, 255, 0, 0); // ARGB for the color, in this case red
int removeColor = p.getColor(); // store this color's int for later use
// Next, set the alpha of the paint to transparent so the color can be removed.
// This could also be non-transparent and be used to turn one color into another color
p.setAlpha(0);
// then, set the Xfermode of the pain to AvoidXfermode
// removeColor is the color that will be replaced with the pain't color
// 0 is the tolerance (in this case, only the color to be removed is targetted)
// Mode.TARGET means pixels with color the same as removeColor are drawn on
p.setXfermode(new AvoidXfermode(removeColor, 0, AvoidXfermode.Mode.TARGET));
// draw transparent on the "brown" pixels
c.drawPaint(p);
// mb should now have transparent pixels where they were red before
user487252's solution works like a charm up until API level 16 (Jelly Bean), after which AvoidXfermode does not seem to work at all.
In my particular use case, I have rendered a page of a PDF (via APV PDFView) into a pixel array int[] that I am going to pass into Bitmap.createBitmap( int[], int, int, Bitmap.Config ). This page contains line art drawn onto a white background, and I need to remove the background while preserving the anti-aliasing.
I couldn't find a Porter-Duff mode that did exactly what I wanted, so I ended up buckling and iterating through the pixels and transforming them one by one. The result was surprisingly simple and performant:
int [] pixels = ...;
for( int i = 0; i < pixels.length; i++ ) {
// Invert the red channel as an alpha bitmask for the desired color.
pixels[i] = ~( pixels[i] << 8 & 0xFF000000 ) & Color.BLACK;
}
Bitmap bitmap = Bitmap.createBitmap( pixels, width, height, Bitmap.Config.ARGB_8888 );
This is perfect for drawing line art, since any color can be used for the lines without losing the anti-aliasing. I'm using the red channel here, but you can use green by shifting 16 bits instead of 8, or blue by shifting 24.
Pixel by pixel is not a bad option. Just don't call setPixel inside your loop. Fill an array of argb ints with getPixels, modify it in place if you don't need to preserve the original, and then call setPixels at the end. You can do this row-by-row if memory is a concern, or you can just do the whole thing in one shot. You don't need to fill a whole bitmap for your overlay color since you'd just be doing a simple replace (if current pixel is color1, set to color2).