web-dev-qa-db-ja.com

ピカソの丸い角

ピカソで角を丸くする合理的な方法はありますか?

  1. 描画が大幅に遅くなることはありません
  2. ハードウェアレイヤーで動作します
  3. 画像ごとに余分なビットマップを作成しません
  4. ダウンロードしたビットマップのサイズを宛先のimageviewのサイズに変更できます

角の丸いピカソのアドバイスのほとんどは、変換を使用することを示唆していますが、変換の一部として余分なビットマップを作成しない例は見たことがありません。

これは、ピカソがビットマップのみを使用しているのに対し、丸みを帯びた角を作成するトリックは、丸みを帯びた角を合理的に効率的に動的に描画できるという事実を使用しているためと思われます(ほとんどのソリューションは http:// www。 curious-creature.org/2012/12/11/Android-recipe-1-image-with-rounded-corners/ )。

Volleyでこれを行うのは少しハッキーでしたが、ImageViewのタイプを、角を丸くしたカスタムドローアブルを使用するものに変更するだけで可能でした。ピカソはビットマップを必要とするので(少なくとも、ビットマップ->ビットマップ変換のみがあります)、ドローアブルをビットマップに変換するとプロセスでビットマップが作成されるため、これは不要です。

1つの解決策は、ビットマップ->ドローアブル変換を追加したブランチのピカソを自分で変更する作業を行うことですが、これを行うためのより良い方法があると思います。

ビューの上に9パッチを描画して、角が丸くなったように見せたくありません。

12
secureboot

編集:私が提案する答えは、ピカソ2.3を待つか、今すぐgithubをフォークすることです。ここで、実際にBitmapDrawableを入手できます。

これまでに見つけたアプローチの1つは、画像をTargetオブジェクトにロードし、その方法でビットマップからカスタムドローアブルを作成してから、ドローアブルをImageViewに設定すると、新しいビットマップを作成せずに描画できるというものです。

ただし、このアプローチにはいくつかの理由があります。

1)ターゲットオブジェクトを管理する必要があります。これらは(ありがたいことに)参照が弱いため、自分で追跡する必要があります。いや。メモリリークが発生しました。

2)コールバックを受け取ったら、世界の状態がまだ画像に関連していることを確認する必要があります。これは、ピカソを使用して避けたいことの一部です。

要するに、より良い解決策を妨げるように思われることがいくつかあります。

1)PicassoはビットマップをPicassoDrawablesでラップします。これは、カスタムimageViewで任意のドローアブルを処理する必要があることを意味します(そのルートを使用する場合)、またはこのクラスの特別な場合。 2)PicassoDrawableはソースビットマップを公開しないため、ドローアブルをビットマップに変換する必要があります(新しいビットマップを作成する必要があります、afaict)。 3)ビットマップ->ドローアブル変換関数はありません(理由については#1を参照してください)。

私が見逃しているものがあるかどうか、または誰かがより良い解決策を考え出したかどうか聞いてみたいです。今のところ、私の最善の計画は、上記で提案したターゲット管理を実行するか、picassoリポジトリをフォークし、PicassoDrawableを変更して基になるビットマップのパブリックアクセサーを作成し、imageViewでその方法でカスタムドローアブルに変換することです。

2
secureboot
  1. このコードは私にとってはうまく機能します
    enter image description here

    Picasso.with(getApplicationContext())
            .load(sp.getString("image_url", ""))
            .transform(new RoundedTransformation(100, 0))
            .fit()
            .into(userProfileImg);
    

//これがmakeのクラスです

    public class RoundedTransformation implements
        com.squareup.picasso.Transformation {
    private final int radius;
    private final int margin; // dp

    // radius is corner radii in dp
    // margin is the board in dp
    public RoundedTransformation(final int radius, final int margin) {
        this.radius = radius;
        this.margin = margin;
    }

    @Override
    public Bitmap transform(final Bitmap source) {
        final Paint paint = new Paint();
        Paint.setAntiAlias(true);
        Paint.setShader(new BitmapShader(source, Shader.TileMode.CLAMP,
                Shader.TileMode.CLAMP));

        Bitmap output = Bitmap.createBitmap(source.getWidth(),
                source.getHeight(), Config.ARGB_8888);
        Canvas canvas = new Canvas(output);
        canvas.drawRoundRect(new RectF(margin, margin, source.getWidth()
                - margin, source.getHeight() - margin), radius, radius, Paint);

        if (source != output) {
            source.recycle();
        }

        return output;
    }

    @Override
    public String key() {
        return "rounded";
    }
}
26
Bharat singh

私もこのようなものが必要でしたが、境界線がありました。インターネットを検索したところ、見栄えの良いバージョン(角が丸くない)が1つ見つかりましたが、境界線が画像の上にあり、気に入らなかった。そこで、画像の外側に境界線を付けて独自のバージョンを作成しました。

public class BitmapBorderTransformation implements Transformation {
private int mBorderSize;
private int mCornerRadius = 0;
private int mColor;

public BitmapBorderTransformation(int borderSize, int color) {
    this.mBorderSize = borderSize;
    this.mColor = color;
}

public BitmapBorderTransformation(int borderSize, int cornerRadius, int color) {
    this.mBorderSize = borderSize;
    this.mCornerRadius = cornerRadius;
    this.mColor = color;
}

@Override 
public Bitmap transform(Bitmap source) {
    int width = source.getWidth();
    int height = source.getHeight();

    Bitmap image = Bitmap.createBitmap(width, height, source.getConfig());
    Canvas canvas = new Canvas(image);
    canvas.drawARGB(0, 0, 0, 0);

    Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    Rect rect = new Rect(0, 0, width, height);


    if(this.mCornerRadius == 0) {
        canvas.drawRect(rect, Paint);
    }
    else {
        canvas.drawRoundRect(new RectF(rect),
                this.mCornerRadius, this.mCornerRadius, Paint);
    }

    Paint.setXfermode(new PorterDuffXfermode((PorterDuff.Mode.SRC_IN)));
    canvas.drawBitmap(source, rect, rect, Paint);

    Bitmap output;

    if(this.mBorderSize == 0) {
        output = image;
    }
    else {
        width = width + this.mBorderSize * 2;
        height = height + this.mBorderSize * 2;

        output = Bitmap.createBitmap(width, height, source.getConfig());
        canvas.setBitmap(output);
        canvas.drawARGB(0, 0, 0, 0);

        rect = new Rect(0, 0, width, height);

        Paint.setXfermode(null);
        Paint.setColor(this.mColor);
        Paint.setStyle(Paint.Style.FILL);

        canvas.drawRoundRect(new RectF(rect), this.mCornerRadius, this.mCornerRadius, Paint);

        canvas.drawBitmap(image, this.mBorderSize, this.mBorderSize, null);
    }

    if(source != output){
        source.recycle();
    }
    return output;
}

@Override 
public String key() {
    return "bitmapBorder(" +
            "borderSize=" + this.mBorderSize + ", " +
            "cornerRadius=" + this.mCornerRadius + ", " +
            "color=" + this.mColor +")";
 }
}

ここにいくつかのサンプルがあります:

また、角を丸くせずに境界線を作成することもできます。
新しいBitmapBorderTransformation(3、Color.WHITE);

5
Cristian Olaru

これは、あらゆるサイズのあらゆる画像で機能します-

1)最初に異なる解像度の空の画像コンテナを作成します2)次に実行時にこれによってその高さと幅を取得します-------

BitmapFactory.Options dimensions = new BitmapFactory.Options(); 
dimensions.inJustDecodeBounds = true;
Bitmap mBitmap = BitmapFactory.decodeResource(activity.getResources(), R.drawable.icon, dimensions);
        int height = dimensions.outHeight;
        int width =  dimensions.outWidth;

3)

Picasso.with(getActivity())
            .load(url)
            .error(R.drawable.image2)
            .placeholder(R.drawable.ic_drawer)
           .resize(width, height )
            .transform(new ImageTrans_roundedcorner())
            .into(imageView1);

4)変換クラス----

import Android.graphics.Bitmap;
import Android.graphics.Canvas;
import Android.graphics.Color;
import Android.graphics.Paint;
import Android.graphics.PorterDuff.Mode;
import Android.graphics.PorterDuffXfermode;
import Android.graphics.Bitmap.Config;
import Android.graphics.Rect;
import Android.graphics.RectF;
import com.squareup.picasso.Transformation;

public class ImageTrans_roundedcorner implements Transformation{

    private int mBorderSize=10;
    private int mCornerRadius = 20;
    private int mColor=Color.BLACK;

    @Override
    public Bitmap transform(Bitmap source) {
        // TODO Auto-generated method stub
        Bitmap output = Bitmap.createBitmap(source.getWidth(), source.getHeight(), Config.ARGB_8888);
        Canvas canvas = new Canvas(output);

        final int color = 0xff424242;
        final Paint paint = new Paint();
        final Rect rect = new Rect(0, 0, source.getWidth(), source.getHeight());
        final RectF rectF = new RectF(rect);
        final float roundPx = mCornerRadius;

        Paint.setAntiAlias(true);
        canvas.drawARGB(0, 0, 0, 0);
        Paint.setColor(color);
        canvas.drawRoundRect(rectF, roundPx, roundPx, Paint);

        Paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
        canvas.drawBitmap(source, rect, rect, Paint);

     // draw border
        Paint.setColor(color);
        Paint.setStyle(Paint.Style.STROKE);
        Paint.setStrokeWidth((float) mBorderSize);
        canvas.drawRoundRect(rectF, mCornerRadius, mCornerRadius, Paint);
        //-------------------

            if(source != output) source.recycle();

            return output;
    }

    @Override
    public String key() {
        // TODO Auto-generated method stub
        return "grayscaleTransformation()";
    }

}
3
amit