android Paint.setShadowLayer() vs Canvas.drawbitmap() problems - android

I use the following code to draw a bitmap during onDraw of a custom View
Paint p = new Paint(Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG);
p.setShadowLayer(3,3,3,0xff000000);
Bitmap bmp = BitmapFactory.decodeResource(some drawable jpg);
canvas.drawBitmap(bmp,null,new Rect(blah blah),p);
and the shadow looks funny. What do I mean funny? I mean that I get a different shadow then if I was calling canvas.drawRect(). It looks sorta like the android shadow code is treating the bitmap as an alpha channel or something.
have tried adding p.setColor(0xff000000); and p.setStyle(Paint.Style.FILL); but not difference.
I guess I could drawRect with shadow on, then drawBitmap with shadow off, but that seems silly as it would be rendering pixels twice.

Basically the shadow layer doesn't work for anything except text. It's real dumb. Check the Android hardware acceleration supported operations chart.
This question was asked back in 2010 when hardware accelerated view trees didn't exist.. based on things I've read, even then the shadow layer only worked for simple shapes (if at all), and others got weird results using it on anything but text. You might be out of luck.
Finally, there are many ways you can fake a shadow layer. You can wrap a view in another view and draw underneath it. You can write a view that draws the shadow yourself as a radial gradient, etc. But you probably just want to make a 9patch that looks like a shadow and use that.
2018 Update
It looks like most of the operations are supported as of api 28! I haven't had a chance to play around with shadow layers recently, but things are looking much more optimistic now.

Maybe http://developer.android.com/reference/android/graphics/Paint.html#isAntiAlias()
can help you.
paint.setAntiAlias(true);

Maybe you should have different Paint objects for different purposes like text, bitmap, etc. So one's setting will not affect others.

Related

android canvas draw text partial

on a canvas is it possible to draw text but make half of it not show up (as if it is being drawn partially off of the canvas, but actually not being off the canvas). i have an indicator on a "graph" with some text and it follows the point but I do not want the text to be drawn out of the graph portion (i am drawing other stuff outside that area).
I also have a background on the layout behind the canvas so I cannot just paint with a bitmap because that would cause some aspect ratio/sizing issues (wouldn't look good).
I have tried looking for answers all over Google, Stack overflow, and by experimentation with no avail. On Google I found many interesting things about drawing text on an android canvas but nothing that I was looking fore, I am pretty stumped, and I am starting to think that what I want is not even possible, and i may need to draw the text custom with points or figure out an alternative that looks just as good.
It's absolutely possible. Probably the fastest is to use clipRect to limit drawing to your graph portion. See this answer: Using clipRect - explanation
The reference on the various forms of clipRect is here: http://developer.android.com/reference/android/graphics/Canvas.html#clipRect(android.graphics.Rect, android.graphics.Region.Op)
If I recall, the whole operation will look something like:
yourCanves.save()
yourCanvas.clipRect(...)
yourCanvas.drawText(...)
yourCanvas.restore()
The restore() call serves to undo the clipRect so you can draw outside it for later drawing.
The simplest solution that popped in my mind, would be to cut using substring the text that you want to dispaly.
Example:
if(MyString >5){
canvas.drawText("VeryLongTe...");
}

Android: Custom masking 2 bitmaps layered one above the other

easy now.
What I want eventually:
I want to have 2 bitmaps overlayed on a view. Same bitmaps with the one above have higher brightness than the below one.
Now when the user strokes(with touch event (like paint brush)) on the upper bitmap, I want those parts of the upper bitmap to go invisible.
For those who are familiar with adobe photoshop perhaps this will make more sense:
I want to draw a mask on an image being display so that only the unmasked parts remain visible. But the mask can be drawn from a brush with variable hardness/size.
How do I achieve this functionality? Direct me in in the line where I should research or give sample code.
Also, is it possible to draw strokes on an imageview with a brush which has variable hardness? I know that I can drawPath and drawArc on a canvas, but I do not know how to achieve the different brush strokes/styles.
Please pardon me if I haven't phrased my question right, or wasn't able to find similar duplicates.
You can use FrameLayout to overlay one image over other in Android and for Custom Masking search FingerPaint on google.
I think the best way is to do your own off-screen compositing, then render the composited image using an ImageView or perhaps a subclass with custom interaction. See this sample code for an example of how to do such compositing using the Porter-Duff transfer modes.

How to implement an eraser for a drawing app in Android

I have been searching all evening for some way to implement an eraser function for my drawing app. The most common answer is to simply paint the background color or image in, but this solution will not work for my application because I am implementing multiple layers (Gimp/Photoshop style).
The user should be able to draw a line with the brush tools provided in as many layers as they like (the onDraw method of my drawingview draws layer0...layerX on top of each other). Then if they choose the eraser tool it should cause any area of the current layer that they trace over to become transparent.
I cannot seem to find an appropriate class/function built in and am unsure how I could write it myself. I tried to do something like
Paint paint = new Paint();
paint.setAlpha(0);
and then use that Paint object to draw with, but that only draws an 'invisible' line.
I also attempted to use
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
but that just seemed to draw as normal and without effect. I'm probably using it incorrectly, but the Android documentation does not contain a clear description of what it does. I just happened to see it in some examples about modifying bitmaps.
I can supply code as needed, I am just not sure what would be helpful to solve my problem. Being pointed in the right direction would be the biggest help as I have not been successful with Google.
You can find the implementation of eraser function, create new canvas, brush function and save function, on this link :
create android drawing interface
it's have very good tutorial for making drawing app on android using motion event.

Android partially anti alias

I'm writing an application that displays large bitmaps in tiles like Google Maps does. A server sends bitmaps that I draw into a scaled/translated canvas. I want this bitmaps to be drawn anti-aliased, but if I enable anti aliasing on the canvas, the edged of the bitmaps are mixed up with the background (none/black) and produce ugly dark lines between the tiles.
Is there a way to tell Android not to antialias the edges of the bitmap on drawing? Or what other soulutions exist for that problem?
You don't enable anti-aliasing on the canvas, you enable it on the Paint object you provide to Canvas.drawBitmap(). So the solution here, I believe, is to use two different Paint objects, the first with AA off for drawing bitmaps, and the second with AA on for drawing everything else.
You may still be interested in using Paint.setDither() or Paint.setFilterBitmap() to affect how the bitmaps are drawn.
Let me answer the question on my own: I got confused because I thought antialiasing was the feature I needed. In fact, setting antialias to false and bitmapfiltering to true on the Paint-object solved the problem. Antialiaising set to true made the ugly lines between the tiles.
Thanks!

Alpha compositing issues

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.

Categories

Resources