Android 毕加索圆角画

Android 毕加索圆角画,android,picasso,Android,Picasso,有没有一种合理的方法可以让毕加索画出圆角呢 不会显著降低绘图速度 使用硬件层 不会为每个图像创建额外的位图 允许将下载的位图调整为目标imageview的大小 大多数关于圆角的毕加索建议都建议使用变换,但我没有看到一个例子不在变换中创建额外的位图 这似乎是因为毕加索只使用位图,而绘制圆角的技巧使用的是这样一个事实,即您可以合理高效地动态绘制圆角(大多数解决方案使用的是类似于位图的东西) 用截击来实现这一点有点老套,但也有可能,只需将ImageView的类型更改为采用自定义可绘制的方式,即绘制圆角

有没有一种合理的方法可以让毕加索画出圆角呢

  • 不会显著降低绘图速度
  • 使用硬件层
  • 不会为每个图像创建额外的位图
  • 允许将下载的位图调整为目标imageview的大小 大多数关于圆角的毕加索建议都建议使用变换,但我没有看到一个例子不在变换中创建额外的位图

    这似乎是因为毕加索只使用位图,而绘制圆角的技巧使用的是这样一个事实,即您可以合理高效地动态绘制圆角(大多数解决方案使用的是类似于位图的东西)

    用截击来实现这一点有点老套,但也有可能,只需将ImageView的类型更改为采用自定义可绘制的方式,即绘制圆角即可。由于毕加索需要位图(至少只有位图->位图转换),这是不可能的,因为将可绘制位图转换为位图会在转换过程中创建位图

    一个解决方案是在我自己的一个分支中修改毕加索,该分支添加了位图->可绘制变换,但我认为有更好的方法来实现这一点


    我不想在视图的顶部绘制一个9面片,以呈现圆角的外观。

    编辑:我建议的答案是等待毕加索2.3,或者现在就开始使用github,在那里您可以使用BitmapDrawable

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

    这种方法有点糟糕,但有几个原因:

    1) 您必须管理目标对象。谢天谢地,这些都是弱引用,所以你必须自己跟踪它们。哎呀。内存泄漏啊

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

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

    1) 毕加索将位图包装在毕加索绘图工具中。这意味着您必须处理自定义imageView中的任意可绘制内容(如果您这样做的话),或者此类的特殊情况。 2) PicassoDrawable不公开源位图,因此必须将可绘制位图转换为位图(需要创建新位图afaict)。 3) 没有位图->可绘制的变换函数(最有可能的原因请参见#1)

    我很想知道我是否遗漏了什么,或者有人提出了更好的解决方案。现在,我的最佳计划是要么执行上面建议的目标管理,要么放弃毕加索回购协议,将毕加索可绘制更改为具有底层位图的公共访问器,并在我的imageView中以这种方式将其转换为自定义可绘制

  • 这段代码对我来说很好

  • //这是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";
        }
    }
    

    我也需要这样的东西,但是有边界。我在网上搜索了一下,发现有一个版本(没有圆角)看起来不错,但边框在图片上方,我不喜欢。因此,我制作了自己的版本,在图像外加上边框

    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,15,Color.WHITE)

    • 无边框圆角:
      新的BitmapBorderTransformation(0,15,Color.WHITE)

    此外,您还可以使用无圆角的边框:

    新的BitmapBorderTransformation(3,颜色.白色)

    这适用于任何大小的图像--

    1) 首先为不同分辨率创建一个空图像容器 2) 然后在运行时,通过以下公式获得其高度和宽度-------

    (三)

    4) 现在转换类----


    你试过了吗?你看过要点了吗?第28行很明显创建了一个新的位图,这正是我试图避免的。我很困惑,伙计们——你们能不能将.background设置为一个具有圆角边框的可绘制文件?(也许我搞不清楚你在iOS/Android中能做什么…:O)毕加索2.3使
    PicassoDrawable
    extend
    BitmapDrawable
    。它避免了额外的分配,并将提供你想要的API。它将有望在本月发布:)留下一个奇怪的红色和边界不适合我;(
    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 +")";
     }
    }
    
    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;
    
    Picasso.with(getActivity())
                .load(url)
                .error(R.drawable.image2)
                .placeholder(R.drawable.ic_drawer)
               .resize(width, height )
                .transform(new ImageTrans_roundedcorner())
                .into(imageView1);
    
    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()";
        }
    
    }