web-dev-qa-db-ja.com

アンチエイリアス処理されていないビットマップ

常に特定の回転で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);を適用すると、これは正しく機能します(ビットマップサーフェスがフィルタリング/スムージングされます)。私は何かが足りないのですか?

No anti-aliasing on the photo

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

UPDATE:私も次のことを試しました:

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

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

19
Eric Kok

ハードウェアアクセラレーションというアンチエイリアシングが発生しなかった理由がわかりました。 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で上記のオープンソースプロジェクトを更新しました。

20
Eric Kok

SetFilterBitmap(true)を使用します。

Paint_object.setFilterBitmap(true);

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

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

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

私のテストコードは

Paint p = new Paint();
p.setAntiAlias(true);
p.setFilterBitmap(true);
canvas.drawBitmap(someBitmap, new Matrix(), p);
19
Swarnendu Paul

私の場合、私はこれをしました、しかしそれはあなたがしたようであるかもしれません:

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

ちょうど試して。

幸運を!

6
Ilya Demidov

私は以前の提案をテストしました、そしてそれらは私のために働きます。多分問題はあなたのビットマップにありますか?たぶんあなたのデバイスに?これは、ビットマップをインラインで作成するコードです。この例が適切かどうかを確認してください。

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

私は同じ問題を抱えていて、これらすべての修正を試しました。最終的に機能したのは、AndroidManifest.xmlファイルでハードウェアアクセラレーションをグローバルに無効にすることです。

 <application
       Android:hardwareAccelerated="false" 
  ...
 >

次に、画像ビットマップをロードするときにinSampleSizeを無効にして、画像がジグザグを回避するのに十分な高品質でロードされるようにします。次に、実際のImageViewの場合、上記のアドバイスを使用します。レイヤータイプをビューに設定します。 .LAYER_TYPE_SOFTWARE、フィルタービットマップがtrueに設定され(上記のように)、アンチエイリアシングがオンになっているPaintオブジェクト。

3
user3522492