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).
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.
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.
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!
I'm currently writing an Android game using surfaceView. I've optimized the game as much as possible and it runs quite smoothly. However, I have collision detection incorporated which is a bit messy. I would like to do collision detection by reading pixels directly from the canvas. Is this possible to do? The closest to this that I have found was to attach a new bitmap to the canvas using setBitmap. Then when I drew to the canvas, the bitmap would be updated. Would this be the way to go? Thanks.
Although you should manage the collision detection in a different way, you can get the pixel color on a given position with the next line of code:
mView.mBitmap.getPixel(j, i)
mView is the View that contains your canvas and mBitmap is the Bitmap with which you created your canvas:
Canvas mCanvas = new Canvas(mBitmap);
From the Canvas API:
The Canvas class holds the "draw"
calls. To draw something, you need 4
basic components: A Bitmap to hold the
pixels, a Canvas to host the draw
calls (writing into the bitmap), a
drawing primitive (e.g. Rect, Path,
text, Bitmap), and a paint (to
describe the colors and styles for the
drawing).
So you wouldn't ever ask a canvas for pixel data, because the canvas itself doesn't really "own" pixel data. The canvas which you use to make draw calls is always attached to a bitmap (the one you're drawing on), so that bitmap is where you should get your pixel data from.
Collision detection is usually costly, but going to a bitmap-based process could make it even worse, depending on what you're trying to do. Just a heads up.
I agree with Josh. If precision is that important in your app, you may want to incorporate screen size/resolution data into some kind of physics engine. Trying to build a physics engine based entirely on visual processing is probably unnecessarily costly.
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.