I want to draw an oval shape inside another oval shape, but the second one should be cut off when it reaches the border of the first one.
This is the desired result:
How can this be achieved?
I want to draw an oval shape inside another oval shape, but the second one should be cut off when it reaches the border of the first one.
As pskink said, you could use PorterDuffXfermode to implement this feature, here is an simple :
public class DrawView : View
{
public DrawView(Context context):base(context)
{
}
protected override void OnDraw(Canvas canvas)
{
base.OnDraw(canvas);
Paint paint = new Paint();
paint.SetARGB(255, 255, 0, 0);
RectF oval2 = new RectF(60, 100, 300, 200);
canvas.DrawOval(oval2, paint);
//PorterDuff.Mode.SrcAtop means Discards the source pixels that do not cover destination pixels. Draws remaining source pixels over destination pixels
paint.SetXfermode(new PorterDuffXfermode(PorterDuff.Mode.SrcAtop));
paint.Color = Color.Black;
RectF oval3 = new RectF(110, 150, 350, 250);
canvas.DrawOval(oval3, paint);
this.SetLayerType(LayerType.Software, null);
paint.SetXfermode(null);
}
}
Effect :
Related
I am new in android. I am trying to draw this image(match statistic)
and fill the image with color with 10% to 100% . I tried this much and this is image
this is the code
public class DrawView extends View {
Paint paint = new Paint();
public DrawView(Context context) {
super(context);
}
#Override
public void onDraw(Canvas canvas) {
paint.setColor(Color.BLACK);
paint.setStrokeWidth(3);
canvas.drawRect(30, 30, 100, 100, paint);
paint.setStrokeWidth(0);
paint.setColor(Color.GRAY);
canvas.drawRect(33, 60, 97, 97, paint);
paint.setColor(Color.WHITE);
canvas.drawRect(33, 33, 97, 60, paint);
}
Any Suggestion will be much helpful for me.
Thanks in advance.
I would prepare two images - fully filled and not filled (only stroke). Having that, load them as two Bitmap objects and then draw like that:
float fillProgress = 0.1f; // let's say image is 10% filled
canvas.drawBitmap(onlyStroke, 0f, 0f, null); // draw just stroke first
canvas.save();
canvas.clipRect(
0f, // left
getHeight() - fillProgress * getHeight(), // top
getWidth(), // right
getHeight() // bottom
);
canvas.drawBitmap(filled, 0f, 0f, null); // region of filled image specified by clipRect will now be drawn on top of onlyStroke image
canvas.restore();
Using two images, outlined and filled e.g. below.
The code above does the following:
draw outline.
apply clip (crop) area.
draw filled shape with crop applied.
remove clip, image as desired.
Applying different clip sizes, you can get the % of fill you require. e.g.
I am trying to programmatically create a gray Rect and black Rect with BlurMaskFilter layer (drop shadow effect) by overriding onDraw in a custom View. I am able to get it to draw on screen without any issues, but when I try to draw the view to a bitmap the results are different. In drawing to bitmap, it appears BlueMaskFilter is applied to the View rather than the specific layer of the black Rect.
What am I missing to make the drawn bitmap same as the output drawn on screen?
CustomView's onDraw override:
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// draw black box (shadow) first
RectF rectShadow = new RectF();
rectShadow.set(10, 10, 120, 120);
Paint shadowPaint = new Paint();
shadowPaint.setMaskFilter(new BlurMaskFilter(5, Blur.NORMAL));
shadowPaint.setStyle(Paint.Style.FILL);
shadowPaint.setColor(Color.DKGRAY);
shadowPaint.setAntiAlias(true);
canvas.drawRect(rectShadow, shadowPaint);
setLayerType(View.LAYER_TYPE_SOFTWARE, shadowPaint);
// draw grey box
RectF rectGray = new RectF();
rectGray.set(0, 0, 100, 100);
Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.parseColor("#656565"));
paint.setAntiAlias(true);
canvas.drawRoundRect(rectGray, paint);
}
Function to save view to bitmap:
public void saveViewToBitmap( View customView int outWidth, int outHeight ) {
customView.setLayoutParams(new ViewGroup.LayoutParams(outWidth, outHeight));
customView.measure(
ViewGroup.MeasureSpec.makeMeasureSpec(customView.getLayoutParams().width,
ViewGroup.MeasureSpec.EXACTLY),
ViewGroup.MeasureSpec.makeMeasureSpec(customView.getLayoutParams().height,
ViewGroup.MeasureSpec.EXACTLY));
customView.layout(0, 0,
customView.getMeasuredWidth(), customView.getMeasuredHeight());
customView.requestLayout();
Bitmap outputBitmap = Bitmap.createBitmap(outWidth, outHeight, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(outputBitmap);
customView.draw(canvas);
return outputBitmap;
}
Note in the following images the screen image has crisp edges for the gray rect, whereas the drawn bitmap has the top and left edges of the gray rect blurred demonstrating the problem.
Image on screen:http://i.stack.imgur.com/0Hl0t.png
Image saved from bitmap created by saveViewToBitmap: http://i.stack.imgur.com/xNzi5.png
Thanks!
I'm working with canvas im my application and I need to draw a circle.
To do that, I'm using the drawCicle(cx, cy, radious, paint) method for the canvas class.
The problem is that the circle's edges appear pixellated. And its kinf of oval.
This is my code:
public void drawCircle(){
Paint paint = new Paint();
paint.setColor(Color.rgb(52, 73, 94));
canvas.drawCircle(200, 300, 33, paint);
}
Use paint.setFlags(Paint.ANTI_ALIAS_FLAG)
This enables anti-aliasing => edges become smoother
Is there any way in Android to draw a filled rectangle with say a black border. My problem is that the canvas.draw() takes one paint object, and to my knowledge the paint object can't have a different color for the fill and the stroke. Is there a way around this?
Try paint.setStyle(Paint.Style.FILL) and paint.setStyle(Paint.Style.STROKE).
Paint paint = new Paint();
Rect r = new Rect(10, 10, 200, 100);
#Override
public void onDraw(Canvas canvas) {
// fill
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.MAGENTA);
canvas.drawRect(r, paint);
// border
paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.BLACK);
canvas.drawRect(r, paint);
}
If you are drawing multiple views then you could also use two paints, one for the stroke and one for the fill. That way you don't have to keep resetting them.
Paint fillPaint = new Paint();
Paint strokePaint = new Paint();
RectF r = new RectF(30, 30, 1000, 500);
void initPaints() {
// fill
fillPaint.setStyle(Paint.Style.FILL);
fillPaint.setColor(Color.YELLOW);
// stroke
strokePaint.setStyle(Paint.Style.STROKE);
strokePaint.setColor(Color.BLACK);
strokePaint.setStrokeWidth(10);
}
#Override
protected void onDraw(Canvas canvas) {
// First rectangle
canvas.drawRect(r, fillPaint); // fill
canvas.drawRect(r, strokePaint); // stroke
canvas.translate(0, 600);
// Second rectangle
int cornerRadius = 50;
canvas.drawRoundRect(r, cornerRadius, cornerRadius, fillPaint); // fill
canvas.drawRoundRect(r, cornerRadius, cornerRadius, strokePaint); // stroke
}
You draw a rectangle with the color of the border and the size of the rectangle plus the border, you change the color of the paint and draw again the rectangle with the normal size.
Is there a way to set a background image for a rectangle drawn in a canvas ?
For exemple i have the following onDraw method :
protected void onDraw(Canvas canvas) {
this.setBackgroundGradient();
RectF rect = new RectF();
rect.set(0, 0, canvas.getWidth(), 50);
canvas.drawRoundRect(rect, 0, 0, this.paint);
}
private void setBackgroundGradient()
{
this.paint.setShader(new LinearGradient(0, 0,0, getHeight(), 0xff919191, 0xff424242, Shader.TileMode.MIRROR));
}
I would like to change my gradient by a background image (repeatable if possible).
Note : i would rather to keep rectangle and not use drawBitmap.
A Rect is not a drawable, it is a convenience class and only holds the four values that define the rect. Canvas knows how to draw a rect with the Paint object you give it.
If you want to have a background (image) instead of a rect, then you either use drawBitmap on the canvas or have a (bitmap)drawable that you pass the canvas to when drawing.