21

私はいつも一定の回転でViewを描く癖があります。Bitmapメソッドを上書きしonDraw、 を回転させ、Canvasアンチエイリアスを使用してビットマップを描画し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();
}

ただし、ビットマップのエッジは常にギザギザになります。丸みを帯びた四角形のエッジが適切にアンチエイリアス処理されていることに注意してください。また、p.setFilterBitmap(true);これを適用すると (ビットマップ サーフェスがフィルター処理/スムーズ化されます) 正しく動作します。何か不足していますか?

写真にアンチエイリアスなし

以下は、リソースからロードされた非アンチエイリアス ビットマップを描画するビューを示す 1 つの画面の分離された例を含む最小限の Android プロジェクトです: https://bitbucket.org/erickok/antialiastest

更新:次のことも試しました:

    Paint p = new Paint();
    p.setAntiAlias(true);
    p.setFilterBitmap(true);
    p.setDither(true);
    canvas.drawBitmap(someBitmap, 0, 0, p);

setFilterBitmapしかし、これは表面をフィルタリングするので役に立ちません。エッジをアンチエイリアスしません。また、コンストラクターsetAntiAliasでフラグを直接設定するのと同じことを行います。Paint疑問がある場合は、私の最小限のテスト プロジェクトを試してください。助けてくれてありがとう!

4

5 に答える 5

22

setFilterBitmap(true) を使用します。

paint_object.setFilterBitmap(true);

それは私にとってもうまくいきます..私はこの質問からそれを得ました

アンチエイリアスを使用して回転したビットマップを描画する

AntiAliasフラグとFilterBitmapフラグの両方を true に設定すると、一緒にビットマップのエッジが滑らかになります。Samsung Galaxy Ace、android 2.2 でテストしました ...

私のテストコードは

Paint p = new Paint();
p.setAntiAlias(true);
p.setFilterBitmap(true);
canvas.drawBitmap(someBitmap, new Matrix(), p);
于 2013-01-19T06:55:09.000 に答える
19

アンチエイリアシングが得られなかった理由、つまりハードウェアアクセラレーションを見つけました。私が(偶然に)Nexus Oneでテストした後、突然動作しましたが、Nexus7は動作しませんでした。ハードウェアアクセラレーションを使用して描画されANTI_ALIAS_FLAGた場合、は何もしません。Canvasその洞察で、私はStackOverflowでRomainGuyの答えを見つけました。これは私の質問に答えます。

解決策は次のように思われます:すべてのビットマップに(手動またはオンザフライで)透明な境界線を追加するか、「シェーダーで何かを行う」。どちらも私にはあまり魅力的ではありません。代わりに、メソッドを使用してカスタムビューでハードウェアアクセラレーションを無効にしました。setLayerTypeこれはAPIレベル11以降で利用可能ですが、(偶然ではなく)ハードウェアアクセラレーションに対処する必要はありません。そこで、ビューコンストラクターに次のように追加しました。

    if (android.os.Build.VERSION.SDK_INT >= 11) {
        setLayerType(View.LAYER_TYPE_SOFTWARE, null);
    }

興味のある方のために、BitBucketで上記のオープンソースプロジェクトを更新しました。

于 2013-01-22T12:59:12.907 に答える
5

私の場合、私はこれをしましたが、あなたがしたのが好きかもしれません:

Paint paint = new Paint();
paint.setAntiAlias(true);

ちょうど試して。

幸運を!

于 2013-01-17T12:06:53.563 に答える
4

以前の提案をテストしましたが、うまくいきました。多分問題はあなたのビットマップにありますか?多分あなたのデバイスで?ビットマップをインラインで作成するコードを次に示します。この例が機能するかどうかを確認してください。

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();
    }
  }
}
于 2013-01-21T17:23:08.693 に答える