android – Bitmap not drawn anti-aliased-ThrowExceptions

Exception or error:

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?

No anti-aliasing on the photo

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!

How to solve:

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.

###

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 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();
    }
  }
}

###

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.

Leave a Reply

Your email address will not be published. Required fields are marked *