何時間もかけて何かに取り組み、あきらめ、質問をし、20分後に答えに出くわすことができるのはなぜですか?人生の喜び。
Path path = new Path();
path.addCircle(kHorizontalOffset, kScreenVerticalOffset, radius, Path.Direction.CW);
canvas.clipPath(path);
任意のパスを取得してクリッピング領域として使用するclipPathメソッドを見逃していました。パスにマスキングサークルを追加すると、必要な処理が正確に実行されます。
[編集]
これはうまく機能しますが、問題があります。ハードウェアアクセラレーションがオンになっている場合は機能しません。加速をオフにすることはできますが、それでは複雑な残りのドローで多くのパフォーマンスが失われます。
これが私が最終的にそれを解決した方法です:
でonSizeChanged()
、ビットマップマスクを作成します。このペイントを使用して、ビットマップの適切な場所に透明な円を描きます。の鍵は、を使用することPorterDuffXfermode
です。
maskPaint = new Paint();
maskPaint.setColor(Color.TRANSPARENT);
maskPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
maskPaint.setStyle(Paint.Style.FILL);
次に、ビットマップを作成します
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
createMask(w,h,this.radius);
}
private void createMask(int w,int h, int radius){
if (mask!=null){mask.recycle();}
mask = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
Canvas maskCanvas = new Canvas(mask);
maskCanvas.drawCircle(w, h, radius, maskPaint);
}
次に、onDraw()で、ビュー全体にマスクを描画します。
@Override
protected void onDraw(Canvas canvas){
// draw the image();
setRadius(drawGmpImage(this.gmpImage, canvas));
canvas.drawCircle(kHorizontalOffset, kScreenVerticalOffset, radius , maskPaint);
// overlay the mask bitmap
if (mask != null) {
canvas.drawBitmap(mask, 0f, 0f, bitmapPaint);
}
半径が変更されると、マスクが再作成されます。
private void setRadius(int radius){
this.radius = radius;
createMask(kHorizontalOffset, kScreenVerticalOffset, radius);
}