I have a custom View
that always draws a Bitmap
at a certain rotation. I overwrite the onDraw
method, rotate the Canvas
a
I had the same problem, and tried all of these fixes. What finally worked is globally disabling hardware acceleration in the AndroidManifest.xml file:
<application
android:hardwareAccelerated="false"
...
>
and then disabling inSampleSize when I loaded my image bitmap, so that (I presume) the image would load at a high enough quality to avoid any zigzags, and then, for my actual ImageView, using the above advice: setting the layer type to View.LAYER_TYPE_SOFTWARE, with a paint object with the filter bitmap set to true (as above) and anti-aliasing on.
In my case I did this, but may be it likes you did :
Paint paint = new Paint();
paint.setAntiAlias(true);
Just try.
Good luck!
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.
I tested the previous suggestions and they do work for me. Maybe the issues is in your bitmap ? Maybe in your device? Here is a code that creates the bitmap inline. Check if this example works for you.
public class BitmapRotateActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new MyView(this));
}
class MyView extends View {
Bitmap bitmap;
public MyView(Context context) {
super(context);
bitmap = Bitmap.createBitmap(160, 160, Bitmap.Config.RGB_565);
Paint p = new Paint();
p.setColor(Color.RED);
p.setStyle(Paint.Style.FILL);
Canvas c = new Canvas(bitmap);
c.drawRect(0, 0, bitmap.getWidth(), bitmap.getHeight(), p);
}
@Override
protected void onDraw(Canvas canvas) {
Paint pbg = new Paint();
pbg.setStyle(Paint.Style.FILL);
pbg.setColor(0xffe0e0ff);
canvas.drawRect(0, 0, getWidth(), getHeight(), pbg);
Paint p = new Paint();
p.setAntiAlias(true);
p.setFilterBitmap(true);
canvas.save();
canvas.rotate(3F, getWidth() / 2, getHeight() / 2);
canvas.drawBitmap(bitmap, 30, 30, p);
canvas.restore();
}
}
}
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);