How to "set up" a paint to accomplish the "second" image above?
paint.setColor(Color.BLACK);
canvas.drawText(strValue, x, y, paint);
First Image: text all in black as result of that code above.
Second Image: better constrat to backgroud colors (edited with graphic editor just to illustrate here)
Note that "31" is partially black and partially white (but it could be any other color with a better contrast to red, as "36" could be to blue).
You could draw with PixelXorXfermode.
the only solution I could think of is that first on your onDraw you have a variable Canvas that you equals to the actual one and then you draw your number,
paint.setColor(Color.BLACK);
canvas.drawText(strValue, x, y, paint);
then you draw the red Rect
canvas.drawRect(myRect, redPaint);
then you draw your line
canvas.drawline(mStartX,mStartY, mFinishX, mFinishY, myLinePaint);
and at the very end outside your onDraw, you call a method like this one:
public void myMethod(){
Paint paint = new Paint();
paint.setColor(Color.BLACK);
this.canvas.drawText(strValue, x, y, paint);
//here you will define the area that you will mark as dirty
//(wich can have the same values as your red Rect)
Rect myRect = new Rect();
myRect.set(x0,y0,x1,y1);
//and finally here you invalidate ONLY the red area
this.canvas.invalidate(myRect);
}
Note: this will require that on your onDraw you verify that the global Canvas is not null
and if so, then you equals your global to the actual.
I'm not sure if this will actually work, however is the only solution I could think of doing so.
PixelXorXfermode is not good method when AntiAlias is set.
if you can get the red rectangle, I think use canvas.clipRect is better. like this
textpaint.setColor(black);
canvas.drawText(str,x,y,textpaint);
Rect oldClipRect = canvas.getClipBounds();
canvas.clipRect(rcRed,Op.REPLACE);
textpaint.setColor(white);
canvas.drawText(str,x,y,textpaint);
canvas.clipRect(oldclipRect,Op.REPLACE);
Related
I am trying to create a Black screen with a transparent Hole in the middle of the screen. Here is what i have tried.
#Override
public void draw(Canvas canvas)
{
Paint myPaint = new Paint();
myPaint.setColor(0xC0000000);
canvas.drawRect(mBlackRect, myPaint);
myPaint = new Paint();
myPaint.setColor(Color.TRANSPARENT);
myPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
canvas.drawRect(mTransparentRect, myPaint);
}
The second paint, shows black color instead of transparent. How can i punch a transparent hole in MY SemiBlack Canvas?
you didn't save the canvas, try the code below
Paint myPaint = new Paint();
int sc = canvas.saveLayer(mBlackRect.left, mBlackRect.top,
mBlackRect.right, mBlackRect.bottom, myPaint,
Canvas.ALL_SAVE_FLAG);
myPaint.setColor(0xC0000000);
canvas.drawRect(mBlackRect, myPaint);
myPaint.setColor(Color.TRANSPARENT);
myPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
canvas.drawRect(mTransparentRect, myPaint);
myPaint.setXfermode(null);
canvas.restoreToCount(sc);
You can not really "punch" a hole by "removing pixels" from something already drawn, at least not with a hardware layer. And if you use a software layer, it will be bad for performance.
What you want to do is draw your shape with an alpha mask applied to your paint. A mask will prevent some parts of the shape to be drawn on the canvas, like cutting a piece of paper and stick it on a wall before spreading the painting.
To apply an alpha mask to your paint, you first need to create a bitmap containing the "hole" shape (programmatically or by loading a custom image from resources), then create a BitmapShader from this bitmap with the proper Xfermode (depending if you want the transparent part in your mask bitmap to be cut out or the non-transparent part) and finally apply this shader to your paint before drawing the semitransparent rectangle or anything you want.
Be careful with performance: only create the Paint object once (do not allocate any object in onDraw() because this method gets called up to 60 times per second on the UI thread), and recreate the alpha mask bitmap only when the bounds of your View/Drawable change (if its dimensions depend on the View dimensions of course, otherwise you just create it once).
I'm sorry if I don't have time to give you ready-to-use code but I think you should find plenty of information about the technique I just described and you can start experimenting and figuring out the solution by yourself which is more rewarding I think ;)
Is there a good way of drawing a path (or even just a straight line) on an android canvas where the line is in one color, but outlined with another? Here's what I'm looking to draw:
...the purpose of course being that the line (in my case a dashed line) is easily visible on both a black and white background.
Thanks!
You should first draw a thicker line with the color of the border, over it, you draw another line, at a distance of 1px to every side of the other line, so it will cover the first line, but 1 keeping visible 1px around the second line. something like this:
public void onDraw(Canvas canvas) {
float startX, startY, stopX, stopY;//remenber to inicialize them with actual values
int BORDER_COLOR, INNER_COLOR;//remenber to inicialize them with actual values
Paint paint = new Paint();
paint.setColor( BORDER_COLOR);
canvas.drawLine(startX, startY, stopX, stopY, paint);
paint.setColor( INNER_COLOR);
canvas.drawLine(startX+1, startY+1, stopX-1, stopY-1, paint);
}
draw twice: with different color and different stroke width
I need to draw a bar diagram like the picture showing below. I am able to draw a ordinary bar diagram with filling a color on text view or some layouts. But this is a bit different.
How do I draw a bar diagram with slanting bars?
.
Try Android canvas and custom View. You can use View's onDraw method. The method provides the canvas. You should try drawArc, drawLine, etc. If your bar view contains a textView, you must use a custom viewgroup.
Do something like this in your onDraw of View.
RectF oval = new RectF();
Paint paint = new Paint();
paint.setColor(ContextCompat.getColor(context, R.color.color1));
paint.setStrokeWidth(widthOfArc);
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.STROKE);
canvas.drawPath(path, yourPaint);
oval.set(x1,y1,x2,y2);
//eg:- startAngle = 10, sweepAngle = 40
canvas.drawArc(oval, startAngle, sweepAngle, false, paint);
Please read about how RectF works.
I will update the answer if I found any related blog/tutorial
Calculating start and end angle is pure Mathematics
refer this
http://www.html5canvastutorials.com/tutorials/html5-canvas-arcs/
You have to change the color and keep drawing Arc to get the result.
I have a bitmap that spans the whole screen that will function as texture for a Path object that I need to draw to my canvas. I then have a background image that this textured path needs to be drawn on top of.
I tried using the PorterDuff modes, but nothing seemed to work correctly. I was having a hard time figuring out exactly how the PorterDuff modes act, because none of them seem to act the way I always thought they were supposed to function.
I've figured out a way to texture the path with this test code:
Paint paint = new Paint();
//draw the texture
canvas.drawBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.texture),0,0,paint);
//construct the Path with an inverse even-odd fill
Path p = new Path();
p.setFillType(Path.FillType.INVERSE_EVEN_ODD);
p.addCircle(this.getHeight()/2, this.getWidth()/2, 200, Path.Direction.CCW);
//use CLEAR to remove inverted fill, thus showing only the originally filled section
paint.setXfermode(new PorterDuffXfermode(android.graphics.PorterDuff.Mode.CLEAR));
//draw path
canvas.drawPath(p, paint);
But I can't figure out how to then place that on top of a background image. Am I just using the PorterDuff modes wrong?
Maybe my questions could lead you to your solution:
The paint used in your drawPath call:
What is the paint style?
What is the paint stroke width?
What is the paint stroke/fill color?
If you are not using a stoke/fill color, but a texture instead, where is the call to the paint's setShader (using a BitmapShader)?
I would like to draw bitmap(with specified color) on canvas.
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.RED);
// create bitmap
canvas.drawBitmap(bitmap, 0, 0, paint);
Well, the bitmap is visible on the canvas, but color of drawable didn't change.
Where is the problem?
I would like to draw bitmap(with specified color) on canvas.
A bitmap contains an image and drawing an image in single color doesn't make any sense. What do you expect it to do? Draw a red rectangle? Shapes can be drawn with color, not images...
The Color attribute of your Paint will be ignored. That Paint parameter is used to pass other settings such as anti-aliasing.
I hope this clarifies.
paint.setColor(Color.RED) is irrelevant. If your image comes with an alpha channel and you want it to be drawn in a single color, use ColorFilter instead:
paint.setColorFilter(new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.SRC_IN);