与毕加索的圆角

sec*_*oot 12 android picasso

是否有合理的方式与毕加索做圆角

  1. 不会显着减慢绘图速度
  2. 适用于硬件层
  3. 不为每个图像创建额外的位图
  4. 允许将下载的位图大小调整为目标imageview的大小

大多数关于圆角的毕加索建议都建议使用转换,但我没有看到一个例子,它不会在转换过程中创建额外的位图.

这似乎是因为Picasso只使用位图,而使用圆角的技巧使用了这样一个事实:你可以合理有效地动态绘制圆角(大多数解决方案使用类似于http://www.curious-creature的内容. org/2012/12/11/android-recipe-1-image-with-rounded-corners /).

通过将ImageView的类型更改为采用自定义drawable的东西,可以将Volley的类型更改为圆形角落.由于Picasso需要位图(至少,只有位图 - >位图转换),所以这是不对的,因为drawable转换为位图会在过程中创建一个位图.

一个解决方案就是在我自己的分支中修改毕加索的工作,它添加了一个位图 - >可绘制的变换,但我想有更好的方法来解决这个问题.

我不想在视图顶部绘制9个补丁以给出圆角的外观.

小智 26

  1. 这段代码对我来说很好
    在此输入图像描述

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

//这里是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";
    }
}
Run Code Online (Sandbox Code Playgroud)


Cri*_*aru 5

我也需要这样的东西,但有边框.我搜索了互联网,我发现一个版本(没有圆角)看起来很好,但边框是在图像上,我不喜欢那样.所以我用图像外面的边框制作了自己的版本.

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 +")";
 }
}
Run Code Online (Sandbox Code Playgroud)

以下是一些示例:

你也可以做没有圆角的边框:
new BitmapBorderTransformation(3,Color.WHITE);


sec*_*oot 2

编辑:我建议的答案是等待 Picasso 2.3,或者现在分叉他们的 github,在那里你可以真正获得 BitmapDrawable。

到目前为止我发现的一种方法是,您可以将图像加载到 Target 对象中,以这种方式从位图创建自定义可绘制对象,然后将可绘制对象设置到 ImageView 中,在其中进行绘制而无需创建新位图。

但由于以下几个原因,这种方法有点糟糕:

1)你必须管理目标对象。这些是弱引用的(幸运的是),所以你必须自己跟踪它们。恶心。内存泄漏啊嘿。

2)当你收到回调时,你最好检查一下以确保世界的状态仍然与图片相关,这是你使用picasso要避免的一部分。

简而言之,有一些事情似乎阻碍了更好的解决方案。

1) Picasso 将位图包装在 PicassoDrawables 中。这意味着您必须在自定义 imageView 中处理任意可绘制对象(如果您采用该路线),或者此类的特殊情况。2)PicassoDrawable 不公开源位图,因此您必须将可绘制对象转换为位图(需要创建一个新的位图,afaict)。3) 没有位图 -> 可绘制变换函数(很可能参见#1 了解原因)。

我很想听听我是否遗漏了什么,或者有人提出了更好的解决方案。现在,我最好的计划是要么执行上面建议的目标管理,要么分叉 picasso 存储库,更改 PicassoDrawable 以获得底层位图的公共访问器,并在我的 imageView 中以这种方式转换为自定义可绘制对象。