常に特定の回転で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
UPDATE:私も次のことを試しました:
_ Paint p = new Paint();
p.setAntiAlias(true);
p.setFilterBitmap(true);
p.setDither(true);
canvas.drawBitmap(someBitmap, 0, 0, p);
_
しかし、setFilterBitmap
が表面をフィルタリングするため、これは役に立ちません。エッジのアンチエイリアスは行いません。また、setAntiAlias
は、Paint
コンストラクターでフラグを直接設定するのと同じことを行います。疑わしい場合は、私の最小限のテストプロジェクトを試してください。助けてくれてありがとう!
ハードウェアアクセラレーションというアンチエイリアシングが発生しなかった理由がわかりました。 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で上記のオープンソースプロジェクトを更新しました。
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);
私の場合、私はこれをしました、しかしそれはあなたがしたようであるかもしれません:
Paint paint = new Paint();
Paint.setAntiAlias(true);
ちょうど試して。
幸運を!
私は以前の提案をテストしました、そしてそれらは私のために働きます。多分問題はあなたのビットマップにありますか?たぶんあなたのデバイスに?これは、ビットマップをインラインで作成するコードです。この例が適切かどうかを確認してください。
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();
}
}
}
私は同じ問題を抱えていて、これらすべての修正を試しました。最終的に機能したのは、AndroidManifest.xmlファイルでハードウェアアクセラレーションをグローバルに無効にすることです。
<application
Android:hardwareAccelerated="false"
...
>
次に、画像ビットマップをロードするときにinSampleSizeを無効にして、画像がジグザグを回避するのに十分な高品質でロードされるようにします。次に、実際のImageViewの場合、上記のアドバイスを使用します。レイヤータイプをビューに設定します。 .LAYER_TYPE_SOFTWARE、フィルタービットマップがtrueに設定され(上記のように)、アンチエイリアシングがオンになっているPaintオブジェクト。