I am drawing text on a canvas. I would like to draw a solid circle of color over the text, and only have the circle be painted where it intersects the text. Example:
and what I want to do:
I'm not sure if this is possible, my draw code is simply:
public void onDraw(Canvas canvas) {
canvas.drawText("Hello", x, y, paint);
paint.setColor(orange);
canvas.drawOval(...);
}
I suppose I would need to apply some masking, but not sure how to get started.
follow this tutorial from a googler...
android-shaders-filters
BitmapShader may help you
You can use PorterDuffXfermode in Android to achieve this.
If you use below code it will work fine:
Bitmap original = Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(),
Bitmap.Config.ARGB_8888); // Created from Canvas
Bitmap mask =
Bitmap.createBitmap(getContext().getResources(),R.drawable.mask_image);
Bitmap result = Bitmap.createBitmap(mask.getWidth(), mask.getHeight(),
Config.ARGB_8888);
Canvas tempCanvas = new Canvas(result);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
tempCanvas.drawBitmap(original, 0, 0, null);
paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
tempCanvas.drawBitmap(mask, 0, 0, paint);
paint.setXfermode(null);
canvas.drawBitmap(result, 0, 0, new Paint());
What does PorterDuff.Mode mean in android graphics.What does it do?
Related
I'm trying to put text over map marker but it always appears under it.
First I convert drawable to bitmap and then draw text on it. drawable to bitmap conversion works fine, I only have a problem with text overlay.
I have already tried these:
Adding text to a bitmap in memory in Android
https://stackoverflow.com/a/7328777/3423468
https://stackoverflow.com/a/8831182/3423468
and many more with no luck.
This is my current method:
Bitmap drawableToBitmap(Drawable drawable)
{
var bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
var canvas = new Canvas(bitmap);
if (shouldDrawText)
{
Paint paint = new Paint();
paint.setColor(Color.WHITE);
paint.setStrokeWidth(40);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER)); // Text Overlapping Pattern
//canvas.drawBitmap(bitmap, 0, 0, paint);
canvas.drawText("Testing...", 10, 10, paint);
}
drawable.SetBounds(0, 0, canvas.Width, canvas.Height);
drawable.Draw(canvas);
return bitmap;
}
Any ideas what I'm doing wrong?
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER)); // Text Overlapping Pattern
Here you use SRC_OVER, which means the source will be over the DST will be under. The DST is the new pixels to be drawn.
You should use DST_OVER to draw the new pixels on top of the old pixels.
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OVER)); // Text Overlapping Pattern
See here an overview of how porterduff works
I need to textured some bitmap in ImageView. I use code bellow:
Bitmap original - texture;
Bitmap mask - image that I must textured;
Bitmap result - result image;
Canvas mCanvas = new Canvas(result);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
mCanvas.drawBitmap(original, 0, 0, null);
mCanvas.drawBitmap(mask, 0, 0, paint);
paint.setXfermode(null);
imgView.setImageBitmap(result);
imgView.setScaleType(ScaleType.CENTER);
it's work but I have
mask
and
texture
result image
But I need black borders and circuit of the image. Anybody know solution how to do that?
Solution my problem was very simple. Instead
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
Need to use
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY));
And everything work like charm.
Can we construct a bitmap from a rect.
I draw a bitmap in a rect and want strokes drawn on the bitmap image become part of the image.
I am wondering if I can construct a bitmap from a Rect so the new bitmap has the old image and the strokes as a single image.
Thank You
You can always take a canvas to help you create an already decoded bitmap the way you want:
Bitmap originalBmp = null;//Here goes original Bitmap...
ImageView img = null;//Any imageview holder you are using...
Bitmap modifiedBmp = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);//Configure with your proper size and color
Canvas canvas = new Canvas(modifiedBmp);
//At this point the modified bitmap has the original one, starting from here, you can add any overlay you want...
canvas.drawBitmap(originalBmp, 0, 0, new Paint());
//And do all the other modifications you want here...
canvas.drawLines(new float[]{}, null);
canvas.drawCircle(x, y, radius, null);
//At this point the modified bitmap will have anything you added
img.setImageBitmap(modifiedBmp);
// IF YOU ARE OVERRIDING ONDRAW METHOD
public void onDraw(Canvas canvas){
//Here DO your DRAW BITMAP NOTE: paint must be already created...
canvas.drawBitmap(bt, 0, 0, paint);
paint.setColor(Color.BLACK);
paint.setStrokeWidth(3);
canvas.drawRect(30, 30, 80, 80, paint);
super.onDraw(canvas);
}
Regards!
Yes you can , Using canvas you can draw something on your old bimtap .
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xff424242;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
// do some canvas drawing
canvas.drawBitmap(bitmap, rect, rect, paint);
I'm using the mask a bitmap with another. The operation succeeds well, unfortunately the result of masking seen a slight black border, as you can see in the image:
How do I remove this border? in the source image is not there.
I'll post the code I'm using:
public Bitmap mask(Bitmap source) {
Bitmap targetBitmap = Bitmap.createBitmap(getWidth(),getHeight(),
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(targetBitmap);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
paint.setAntiAlias(true);
paint.setDither(true);
canvas.drawBitmap(source, 0, 0, null);
canvas.drawBitmap(getMask(), 0, 0, paint);
paint.setXfermode(null);
return targetBitmap;
}
where getMask () returns the Bitmap that represents the figure of the Puzzle.
I hope to receive your help, thank you all
Sorry for my english :-)
UPDATE:
the black border is what I point out in this picture:
UPDATE:
place the sequence of transformation. The third image would be identical to the first but without color. The problem is the black edge of the puzzle.
I hope to be more clear:
The way I draw images with mask is kind of the other way around from what you do.
public Bitmap mask(Bitmap source) {
Bitmap targetBitmap = Bitmap.createBitmap(getWidth(),getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(targetBitmap);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
// paint.setAntiAlias(true); // you've already set this in the constructor
paint.setDither(true);
canvas.drawBitmap(getMask(), 0, 0, null);
canvas.drawBitmap(source, 0, 0, paint);
// paint.setXfermode(null); // no need for this
return targetBitmap;
}
Note that PorterDuff.Mode is set to SRC_IN (not DST_in) and that the mask is drawn first and then the image on top of that mask. With this approach you can also draw the previous source as the base mask, add the new (puzzle) mask and then draw the final source/image on top of that with SRC_IN paint to add new puzzle pieces each time.
If that doesn't solve the black border, check that your mask doesn't have feathered (transparent) edges that might be causing these problems.
Also, ANTI_ALIAS_FLAG doesn't do anything on textures. If you want smoothly scaled textures use paint.setFilterBitmap(true);
Following is my program and reference picture.
Program :
int width = src.getWidth();
int height = src.getHeight();
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas (bitmap);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setDither(true);
canvas.drawBitmap(src, 0, 0, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.MULTIPLY));
paint.setColor(Color.RED);
paint.setAlpha(35);
canvas.drawRect(0, 0, width, height, paint);
Reference picture :
I used above program to add a light transparent red color (with alpha) to the photo. But I am not clear why the photo changed to deep deep red. The "ideal result" is made by Photoshop. I just add a red layer before the original photo. And than change to a low transparence and MULTIPLY.
Are they not the same processing concept or my program has anything wrong? Does it can't use Mode.MULTIPLY to create the "ideal result"? Can anybody give some opinion to me?
thanks thanks thanks a lot!
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas mCanvas = new Canvas(bitmap);
Paint paint = new Paint();
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.LIGHTEN));
paint.setColor(Color.RED);
paint.setAlpha(95);
mCanvas.drawBitmap(src, 0, 0, null);
mCanvas.drawRect(0, 0, src.getWidth(), src.getHeight(), paint);
With mode Lighten and Alpha as 95 I'm getting something nearer to your requirement.
Result: