17

次のコードを使用して、正方形のビットマップから円を切り取ろうとしています

        Canvas canvas=new Canvas(bitmapimg );
        int circleXCoord = bitmapimg .getWidth() / 2;
        int circleYCoord = bitmapimg .getHeight() / 2;
        int circleRadius = bitmapimg .getWidth() / 2;

        Rect rect = new Rect(circleXCoord - circleRadius, circleYCoord - circleRadius, circleXCoord + circleRadius, circleYCoord + circleRadius);

        int width = rect.width();
        int height = rect.height();

        Paint paint = new Paint();
        paint.setStyle(Paint.Style.STROKE);
        paint.setColor(Color.BLUE);
        canvas.drawRect(rect, paint);
        canvas.drawBitmap(bitmapimg , rect, rect, paint);
        Path p = new Path();
        p.addCircle(circleXCoord, circleYCoord, width / 2F, Path.Direction.CW);
        canvas.clipPath(p, Region.Op.DIFFERENCE);
        canvas.drawColor(0, PorterDuff.Mode.CLEAR);

アイデアは、正方形(長方形)のビットマップをキャンバスに添付してから、円形のパスをクリップすることです。長方形と円の違いを明確にします(透明にします)。

コードはAndroid4で正常に機能しますが、Android 2.3.3デバイスでは、差分領域が透明ではなく黒で表示されます。

ここに何かが足りないのですか、それともPorterDuff.Mode.CLEARがジンジャーブレッドでサポートされていませんか?Androidで正方形から円を切り取るより良い方法はありますか?

4

3 に答える 3

40

PorterDuff.Mode.Clearはジンジャーブレッドでは機能しなかったようです

問題を解決しました(このコードを使用して正方形から円を切り取ります)

 public Bitmap BitmapCircularCroper(Bitmap bitmapimg){
    Bitmap output = Bitmap.createBitmap(bitmapimg.getWidth(),
            bitmapimg.getHeight(), Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(output);

    final int color = 0xff424242;
    final Paint paint = new Paint();
    final Rect rect = new Rect(0, 0, bitmapimg.getWidth(),
            bitmapimg.getHeight());

    paint.setAntiAlias(true);
    canvas.drawARGB(0, 0, 0, 0);
    paint.setColor(color);
    canvas.drawCircle(bitmapimg.getWidth() / 2,
            bitmapimg.getHeight() / 2, bitmapimg.getWidth() / 2, paint);
    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
    canvas.drawBitmap(bitmapimg, rect, rect, paint);
    return output;

}
于 2012-12-06T06:10:38.730 に答える
5
import android.graphics.PorterDuff.Mode;
import android.graphics.Bitmap.Config;

public static Bitmap getCircularBitmap(Bitmap bitmap) 
{
    Bitmap output;

    if (bitmap.getWidth() > bitmap.getHeight()) {
        output = Bitmap.createBitmap(bitmap.getHeight(), bitmap.getHeight(), Config.ARGB_8888);
    } else {
        output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getWidth(), Config.ARGB_8888);
    }

    Canvas canvas = new Canvas(output);

    final int color = 0xff424242;
    final Paint paint = new Paint();
    final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());

    float r = 0;

    if (bitmap.getWidth() > bitmap.getHeight()) {
        r = bitmap.getHeight() / 2;
    } else {
        r = bitmap.getWidth() / 2;
    }

    paint.setAntiAlias(true);
    canvas.drawARGB(0, 0, 0, 0);
    paint.setColor(color);
    canvas.drawCircle(r, r, r, paint);
    paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
    canvas.drawBitmap(bitmap, rect, rect, paint);

    return output;
}
于 2016-03-02T09:39:27.943 に答える
3

まだこれを見ている人にとって、この答えはいくつかの問題を引き起こします。

1.)このインスタンスで作成しているキャンバスには、ハードウェアアクセラレーションはありません。Paintオブジェクトにはアンチエイリアシングがありますが、キャンバスにはありません。これにより、onDraw()呼び出しでこれを元のキャンバスにペイントして戻すと、アーティファクトが発生します。

2.)これにはさらに多くのリソースが必要です。2番目のビットマップ(OOMを引き起こす可能性があります)、2番目のCanvas、および実行する必要のあるさまざまな変更をすべて作成する必要があります。

RomainGuyの答えをチェックしてください。BitmapShaderを作成してから、Circleを提供するRoundRectを作成します。RectFが円を正しく決定できるように、RectFの寸法を知る必要があります。

これは、中心点(x、y)と半径がわかっている場合、RectFを簡単に決定できることを意味します。

left = x - radius;
top = y - radius;
right = x + radius;
bottom = y + radius;

これは、以下に掲載されているこのソリューションでは、画面に描画する必要があるのは1回だけで、他のすべては画面外のバッファーで行われることも意味します。

http://www.curious-creature.com/2012/12/11/android-recipe-1-image-with-rounded-corners/

最良の解決策はここにあります:

BitmapShader shader;
shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);

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

RectF rect = new RectF(0.0f, 0.0f, width, height);

// rect contains the bounds of the shape
// radius is the radius in pixels of the rounded corners
// paint contains the shader that will texture the shape
canvas.drawRoundRect(rect, radius, radius, paint);
于 2015-08-24T20:51:27.147 に答える