I'm trying out the android graphics classes.
I wanted to draw some arcs/circles with a fill color and black outline.
The Paint class has a style for FILL_AND_STROKE, but there doesn't seem to be a way to set the fill color vs. stroke color. So as far as I can tell it's the same as FILL?
So what's the point of FILL_AND_STROKE if you can't set a separate fill and stroke color?
I haven't managed to find a good explanation.
(I solved my simple problem by doing a fill first, then a stroke, naturally)
Edit:
I ran into this bug report: http://code.google.com/p/android/issues/detail?id=4086
Comment 4 and 5 seem to imply that FILL_AND_STROKE is basically the same as FILL and it will be 'fixed' in 2.2. I guess they'll add a new color?
afaik: FILL fills your circle, while FILL_AND_STROKE also draws the border. If you increase the size of the stroke, it should result in different circles sizes (only visual!)
Think about this: you draw a circle by hand with a small sized pencil. The radius is what you wanted. If you now take a big brush and draw the circle again, your radius is much bigger... (i hope its understandable O.o )
I guess the FILL_AND_STROKE is particularly useful, if one would animate between STROKE and FILL, while wanted to retain the size of the drawn object.
I'm giving an example with the first one below is animated between FILL_AND_STROKE to STROKE, while the second is on just FILL to STROKE. You could easily see the size shrink.
Hence FILL_AND_STROKE is pretty handy here to make size as consistent as possible with others that have STROKE, without have to manually adjust the size of the drawn object (which is complicated)
Yes it's a bit silly. The only use for it is if you want to change between a stroke only and a filled circle then you can use FILL_AND_STROKE to keep the size of the circle the same.
If you went from STROKE to FILL you would lose the width of the stroke when you drew the circle again.
If your stroke style is something other than a solid line (eg a dashed line), you should be able to see the difference. Not that it seems a very useful feature though.
Being able to extend the silhouette of something (more complex than a circle) outwards can be extremely useful though, and not easily obtained by other means
Please see #Shurane's comment.
Just draw it twice, one filled, one stroke and each with one color.
Worked great for me, and gives the impression of a STROKE and a FILL!
Related
There is an issue with anti-alias when trying to draw multiple times at same place using the android Canvas.
First I'm initializing paint = new Paint(Paint.ANTI_ALIAS_FLAG) and then setting stroke cap to Paint.Cap.ROUND.
Then, if I call canvas.drawPoint(x, y, paint) once causes the following result:
While calling canvas.drawPoint(x, y, paint) multiple times (100 in this example) causes this:
I've created an example with minimal code to run this on GitHub: android-canvas-antialias
I noticed if I draw the points with a certain distance, the anti-alias seems to work as expected (first image). But drawing it with little offset causes the same anti-alias issue (second image).
Is there any setup that need to be done for this to work while drawing the points at same place? Or I simply may not be drawing at same place (or with very little offset)?
EDIT: the real issue is because I'm trying to draw a width variable line segment. See the MainActivity.drawSegment on git repository.
I don't think this is a problem, I mean, a bug itself. And even if solvable trivially I guess.
The pixels of the edge of the circle are draw with some alpha, e.g. a red pixel with 25% alpha if you overlay it with more 3 pixels with same alpha you will get a 100% red pixel.
A workaround would be manage all shapes created and check if some of them has the same size + position (maybe color too) and just draw one of them.
The link below explain how the Antialiasing works, might help.
http://web.cs.wpi.edu/~matt/courses/cs563/talks/antialiasing/methods.html
It works correctly. Anti-aliasing is when the edges of the shape are semi-transparent. When you multiply the shapes, the semi-transparent pixels become not transparent and you get "ragged" edges.
The solution is not to do this.
I want to apply the border to this custom view shape
which created by many canvas.draw...() in onDraw()
The border that i want to create and apply to my custom view should have equal range all the way with some distance from the custom view and it should also cover small circle in each slice.
Any idea how to make this?
Thanks.
This isn't so much an answer, but more of a recommendation. Take a look at the Porter-Duff modes available to you. Worst case you may need to do some per pixel image manipulation which should be fine as long as the view isn't animated.
On second thought, here's an idea: why not create two images: one large circle which will always draw behind everything and a second which will always draw behind the small circles. The large circle would just be the complete border you want displayed, whereas the small circles would actually only be a semi circle border, which would render on top of the large circle (covering the large circle border under it). The key would then be to rotate the small border circle depending on where it's located. I hippie that makes sense, but it should work and be very efficient too.
Another option would be to separate the rendering into white circles and slightly larger border color circles. If you render the slightly larger (border color) circles first, then render the normal circles (white) on top, then you won't have to worry about any rotations and it will render correctly if the small outer circles begin to overlap.
So the idea is similar to the first suggestion. You'll still need a large circle and small circle (both white), but in addition, you'll need slightly larger border colored large and small circles.
I hope this description is a little clearer, but I assume that you are comfortable enough with compound drawables to figure out the rest, given that you've gotten this far in making your view.
All the best implementing it, and feel free to ask for any clarification! :)
I need to create the painting application for the kids where kid can colour inside the black bordered sketch of any image
But, I am struck with the problem,that colouring can come outside the black bordering of the image...which i don't want to.Please guys help me to find out how to restrict the colouring by user within the black border of sketch
Also, I want that no colour should cover the black border.it should be inside the border.
I can post my code if required.
Look at Canvas clipPath and use the clipping built in to android to limit the 'coloring' of the kid/user to the regions you specify. You can then draw your objects as layers, kid/user colored layer on bottom, your sketch on top.
Finally..i have implemented it using mask bitmap and right usage of Portet.Duff mode
I drawing a lines from point to point with gradient. To everything looks nice I using rounded caps between them. Problem is that caps are only in one colour. There is possibility to paint them separately or force drawing to do it right?
Or maybe just draw a dot between them?
I found solution.
Like I write before I just gonna draw my own Points between the lines and put there whatever colour I need.
You should use the GradientDrawable with the LINE shape,
Documentation: http://developer.android.com/reference/android/graphics/drawable/GradientDrawable.html
Say I want to create a custom control that would look something like this:
http://karmalita.com/stuff/alpha1.png
The width of the popup balloon can change, and the relative position of the "pointer triangle" can change as well. Of course, additional graphics/text will be drawn on top.
I want it based on images, rather than trying to do the whole thing vector. And of course, the images have varying translucency, which is where the complications arise.
I know there are various ways of doing it (currently I use four images, one of which gets copied a bunch of times....it works but is messy), but I'm interested in finding the easiest, cleanest way. What would be nice would be if I could use a nine-patch for the main rectangle (below left), then draw the pointer triangle (below right) on top of it.
http://karmalita.com/stuff/alpha2.png
But of course that won't work, since the bottom edge of the rectangle will bleed through the pointer triangle, and the shadows will accumulate, etc.
Is there some Porter-Duff magic I can do?
Or should I simply mask the area of the pointer using an inverse clip rect, then draw the nine-patch (stretched appropriately), so it looks like this....
http://karmalita.com/stuff/alpha3.png
....then remove the clip rect, then draw the pointer triangle in the area where the clip rect was?
Or what? Is there an easier/better/more efficient way?
Although I'd love a solution for this specific problem, I'm mostly interested in a general solution for these sorts of scenarios.
Interesting one...
I was about to say "No, there's no way except the inverse clip-rect solution", but I have an (untested) idea:
When you add the arrow section to the regular 9-patch balloon, the result (luckily) is that all the pixels get more opaque.
Therefore (and here's the untested bit) you should be able to pre-calculate a modified version of the 'arrow' patch which - when applied on top of the regular balloon, gives the correct effect: For example the resulting arrow patch would have less shadow where the regular patch already contributes.
I'll let you think about the maths for that, but I guess it's pretty straightforward.