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!
Related
I am wondering if there is a way to draw filled areas (like a filled polygon) with the Android Canvas without using the Path class and call canvas.drawPath(...).
The reason I want to do this without Path is because I have to draw very large datasets and canvas.drawPath(...) is not hardware accelerated and therefore slow.
The performance when using canvas.drawLines(...) is much better because of hardware acceleration, however I have not found a way to draw the polygon filled using this approach (even when the lines are all connected).
Even calling paint.setStyle(Style.FILL) did not fill the polygon when using drawLines(...).
Is there a way to draw a filled-polygon without using the Path approach?
Or is there any other way to improve performance using the Canvas?
You might want to look at opengl view and use it for all the drawings you need. Definitely will be damn fast. Still, all your drawing code needs to be re-written.
You probably need to do something like :
Paint red = new Paint();
red.setColor(android.graphics.Color.RED);
red.setStyle(Paint.Style.FILL);
And use this color for your path, instead of your ARGB. Make sure the last point of your path ends on the first one, it makes sense also.
we had problems to draw nice & smooth images in java, because they were jagged.
This code solved our problem:
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
but now we are making the same app for android, but we have no clue how to apply similar interpolation or antialiasing to an android app.
(we use eclipse emulator)
Use a Paint object.
create a Paint object p
set p.setFilterBitmap(true)
pass the paint p in your Canvas's draw methods
This will activate (bilinear) filtering that will smoothen the "content" of the bitmap. You can also try to activate anti-aliasing with Paint.setAntiAlias(true), but that will affect only the outer edges of the bitmap (it is pretty handy for text though).
I'm developing an Android game using Canvas element. I have many graphic elements (sprites) drawn on a large game map. These elements are drawn by standard graphics functions like drawLine, drawPath, drawArc etc.
It's not hard to test if they are in screen or not. So, if they are out of the screen, i may skip their drawing routines completely. But even this has a CPU cost. I wonder if Android Graphics Library can do this faster than I can?
In short, should I try to draw everything even if they are completely out of the screen coordinates believing Android Graphics Library would take care of them and not spend much CPU trying to draw them or should I check their drawing area rectangle myself and if they are completely out of screen, skip the drawing routines? Which is the proper way? Which one is supposed to be faster?
p.s: I'm targeting Android v2.1 and above.
From a not-entirely-scientific test I did drawing Bitmaps tiled across a greater area than the screen, I found that checking beforehand if the Bitmap was onscreen doesn't seem to make a considerable different.
In one test I set a Rect to the screen size and set another Rect to the position of the Bitmap and checked Rect.intersects() before drawing. In the other test I just drew the Bitmap. After 300-ish draws there wasn't a visible trend - some went one way, others went another. I tried the 300-draw test every frame, and the variation from frame to frame was much greater than difference between checked and unchecked drawing.
From that I think it's safe to say Android checks bounds in its native code, or you'd expect a considerable difference. I'd share the code of my test, but I think it makes sense for you to do your own test in the context of your situation. It's possible points behave differently than Bitmaps, or some other feature of your paint or canvas changes things.
Hope that help you (or another to stumble across this thread as I did with the same question).
I am creating a game for android and I would like the sprites to have the look of an old NES game. I have some 12x12 pixel images and would like them to keep their pixelated look as they are scaled up.
Please view the following link
http://imgur.com/a/LR3eK/all
One image is a screenshot of the image as it looks in an editor. This is how I would like it to look in game. The other image is what it actually looks like blown up in game (blurry).
The image is imported as a Drawable and I'm calling Drawable.draw(Canvas canvas) on it.
I've read up on the problem and found some info here (Android: drawable resolutions). I believe it's either that anti aliasing or some kind of interpolation needs to be disabled but I cannot figure out how to do this with a Drawable.
I did however find out that it is possible with Bitmaps but my game requires lots of sprite re-scaling and, although I found this Resize Bitmap in Android I do not think re-scaling bitmaps is a good idea.
I am new Android and no where near a professional programmer so please shed some light on me.
In my app I had to do the exact same thing!
Paint paint = new Paint();
paint.setDither(false);
paint.setAntiAlias(false);
And I used pixel-sized images to save space, and a Matrix to handle rotation and scaling (though that's your choice).
Hope this helps, good luck!
EDIT:
also if you're using the createScaledBitmap, or any similar functions, make sure you pass false for any filtering parameters.
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.