How can i draw path with translucent (semi-transparent) band on canvas (method onDraw in my custom View)? I draw path line by bezier curve (method path.quadTo), but i want to around the line was illuminated translucent band?
I tried several approaches:
Try draw path by paint with semi-transparent color 0x8800ff00.
Try use paint.setShader(new BitmapShader(semi-transparent background image)) and draw path by this paint;
But they did not help. There was no effect of translucency.
Does it work if you first draw the curve using a Paint with a much bigger StrokeWidth and a transparent color (this being the glow), then draw your first curve on top of it?
Related
I am trying to draw the following shape in a circle on a canvas. I know how to draw a circle using the center, radius and paint variable. But I am trying to draw the figure below.
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 ;)
Imagine that I have a rectangle image. How could I create a style like the next one?
I mean, cropping the image into a circle, add the border, the shadow and the gross /shine effect. Until now, I only have tried this snippet code to crop the image: Cropping circular area from bitmap in Android but just that. I have no idea how to do the remaining components in Android.
An easy way to achieve this effect is to use Canvas.drawCircle() and a BitmapShader:
BitmapShader s = new BitmapShader(myPhoto, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
Paint p = new Paint();
p.setShader(s);
myCanvas.drawCircle(centerX, centerY, radius, p);
To do the shadow, simply call Paint.setShadowLayer() on the paint (this will only work if you draw the effect into an offscreen Bitmap or if your View uses a software layer – set by calling View.setLayerType() –).
The border can be drawn by drawing another circle on top, using the Paint.Style.STROKE style (that you can set by calling Paint.setStyle()).
Finally you can draw the gloss by drawing a circle, oval or Path on top of your very first circle. You'll need to use a LinearGradient shader on your paint and you'll also need to clip the gloss. You can do this in two ways:
If you are drawing the entire effect into a Bitmap, which is what I would recommend, simply set the paint's Xfermode to a new PorterDuffXfermode(PorterDuff.Mode.SRC_IN).
If you are drawing the effect directly on screen you can simply use Canvas.clipPath() to set a circular clip. Note that this will work with hardware acceleration only as of Android 4.3.
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 am drawing several circles with transparency. The number of circles and their positions are not fixed. Currently I am setting the transparent color in a Paint object and drawing the circles in a for loop with the Canvas object. But that causes overlapping.
I have thought of a method:
- Render all the circles as opaque on something other than the main canvas.
- Set the transparency.
- Draw the final object on canvas.
How do i implement that on android?
Create a new bitmap with ARGB888, and draw on it's canvas all your shapes with no transparency.
Then draw the new bitmap into the main canvas using a Paint on which you called setAlpha earlier