I have a custom View
that always draws a Bitmap
at a certain rotation. I overwrite the onDraw
method, rotate the Canvas
and draw the bitmap with an anti-aliased Paint
.
public RotatedImageView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); someBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.placeholder); } @Override protected void onDraw(Canvas canvas) { // Save and rotate canvas canvas.save(); canvas.rotate(3F, getWidth() / 2, getHeight()); // Draw the icon Paint p = new Paint(Paint.ANTI_ALIAS_FLAG); canvas.drawBitmap(someBitmap, 0, 0, p); canvas.drawRoundRect(new RectF(75, 50, 225, 200), 10, 10, p); // All done; restore canvas canvas.restore(); }
However, I always get jagged edges on the Bitmap. Note that the roudned rectangle gets nicely anti-aliased edges. Also, when I apply p.setFilterBitmap(true);
this works (the bitmap surface gets filtered/smoothed) correctly. Am I missing something?
Here's a minimal Android project with isolated example of one screen that shows the View that draws the non-anti-aliased Bitmap, loaded from a resource: https://bitbucket.org/erickok/antialiastest
UPDATE: I have also tried the following:
Paint p = new Paint(); p.setAntiAlias(true); p.setFilterBitmap(true); p.setDither(true); canvas.drawBitmap(someBitmap, 0, 0, p);
But this doesn't help as setFilterBitmap
filters the surface; it does not anti-alias the edges. Also, setAntiAlias
does the same as directly setting the flag in the Paint
constructor. If in doubt, please try my minimal test project. Thanks so much for any help!
Anti-aliasing is the smoothing of jagged edges in digital images by averaging the colors of the pixels at a boundary. The letter on the left is aliased. The letter on the right has had anti-aliasing applied to make the edges appear smoother.
Anti-aliasing smoothes edges by estimating the colors along each edge. Instead of pixels being on or off, they are somewhere in between. For example, a black diagonal line against a white background might be shades of light and dark grey instead of black and white.
Use setFilterBitmap(true).
paint_object.setFilterBitmap(true);
it works for me too.. I got it from this question
Drawing rotated bitmap with anti alias
set both the AntiAlias flag and FilterBitmap flag to true, they together shall make bitmap's edges smooth, I have tested it on Samsung Galaxy Ace , android 2.2 ...
My Testing Code is
Paint p = new Paint(); p.setAntiAlias(true); p.setFilterBitmap(true); canvas.drawBitmap(someBitmap, new Matrix(), p);
I have found why I did not get any anti-aliasing: hardware acceleration. After I (by pure accident) tested on my Nexus One it suddenly worked, while my Nexus 7 didn't. Turns out that the ANTI_ALIAS_FLAG
does nothing when the Canvas
is drawn using the hardware acceleration. With that insight I found Romain Guy's answer on StackOverflow which answers my question.
Solutions seem to be: adding a transparent border to every bitmap (manually or on the fly) or 'do something with shaders'. Neither are very appealing to me. Instead I disabled hardware acceleration on my custom view using the setLayerType
method. Note that this is available since API level 11, but (not by accident) you won't have to deal with hardware acceleration before any way. So I have added, in the view constructor:
if (android.os.Build.VERSION.SDK_INT >= 11) { setLayerType(View.LAYER_TYPE_SOFTWARE, null); }
I've updated the above referenced open-source project on BitBucket for those interested.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With