Hello and sorry for my bad English.
On my application, onDraw() method draws 10x10 field with lines using canvas.
Then, in other method I want some cells to be painted in yellow for example.
The code is:
Paint ship = new Paint();
ship.setColor(getResources().getColor(R.color.ship_color));
Canvas canvas = new Canvas();
Rect r = new Rect(x*(rebro_piece),y*rebro_piece, x*(rebro_piece+1), y*(rebro_piece+1));
canvas.drawRect(r, ship);
but nothing happens. What shall I do?
UPD: am I right, that Canvas only draws within onDraw() method and from nothing else?
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 ;)
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've been stumped by this one for a little bit, so I figured I'd ask here to see if anyone has any pointers.
In a nutshell, I have an app where I want multiple complex shapes to be drawn onto a canvas, which will then be drawn onto the screen (I'll be implementing panning around the large canvas as suggested in this question's answer: Android: Drawing and rotating on a canvas)
How exactly do I go about creating a custom shape and drawing it at arbitrary locations/rotations on a Canvas in Android?
Below is an example of a simple custom shape, as I've tried to implement it so far (typically they'd be created at run-time)
public class Symbol {
public Bitmap b = Bitmap.createBitmap(500, 500, Bitmap.Config.ARGB_8888);
public Symbol() {
Canvas canvas = new Canvas(b);;
Paint paint = new Paint();
paint.setColor(Color.GRAY);
paint.setStyle(Paint.Style.STROKE);
paint.setTextSize(25);
paint.setStrokeWidth(4);
paint.setDither(true);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setAntiAlias(true);
String str="TestStr";
canvas.drawText(str, 250,250, paint);
}
}
Wow, I derped hardcore on this one.
Android: canvas.drawBitmap performance issue
Adding this in my main class made everything happy, at least as far as this simple case went.:
Symbol s = new Symbol();
canvas.save();
canvas.rotate(5);
canvas.drawBitmap(s.b, 0,0, null);
canvas.restore();
I need to implement an eraser for an paint application, that has a canvas:
Canvas canvas = new Canvas(bitmap);
Where bitmap is a mutable Bitmap.
I write on the canvas with the following Paint:
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(0xFF000000);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(50);
Then when i want to erase i do the following:
mPaint.setMaskFilter(null);
mPaint.setColor(Color.TRANSPARENT);
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
But it doesn't work. How can i implement a erase without using the porterDuff mode, or how can i change the code so that it will work.
Like this all it does, it draws lines, just like the pen. but the color instead of being black, its more an grey.
EDIT: I tried something else, and i saved the bitmap value in another bitmap, so that when i press erase, i would get the value back. This works and deletes the drawings but the problem is that, after this if i want to draw something, i draw but it disappears. Is this because the bitmap is no the same as the bitmap from:
Canvas canvas = new Canvas(bitmap);
?
So instead of having a layout on which i add my View. I put one parent layout that includes one layout and one imageview.
I put the background image on the imageview. I put an transparent picture on the child layout. and then bring the child layout to front and it is working now
in the onDraw(Canvas canvas1) method i see how it is possible to draw shapes using the passed argument of "canvas1". However, if i were to create a new Canvas object example":
Canvas canvas2 = new Canvas();
Paint paint = new Paint();
paint.setColor(Color.BLUE);
canvas2.drawRect(55,87,130,600, paint);
canvas2 won't be displayed on screen, how can i get it displayed together with the canvas1 object?
Are you trying to draw layers? Perhaps you need to use a viewgroup such as FrameLayout with two children views: one using canvas1, the other using canvas2.
When you create canvas using Canvas() constructor, your get an empty raster canvas.
As per documentation:
Construct an empty raster canvas. Use setBitmap() to specify a bitmap to draw into.
This means that your drawings are just thrown away unless you explicitly attach bitmap to Canvas object.
I'm using custom ImageViews rendered in a FrameLayout as I explained in this thread.