【问题标题】:ImageView with rounded corners after scaling with ScaleType.CenterCrop使用 ScaleType.CenterCrop 缩放后带有圆角的 ImageView
【发布时间】:2014-11-21 21:47:50
【问题描述】:

我正在尝试裁剪图像,然后将其圆角以使其在屏幕上看起来更漂亮。

我能够做的是围绕图像的角落,但裁剪有时会切断图像的侧面(取决于图像的大小/纵横比)。

所以我想做的是进行裁剪,然后应用圆角。我该怎么做?

圆角图像:

private Bitmap getRoundedCornerBitmap(Bitmap bitmap) {
    Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888);
    Canvas canvas = new Canvas(output);

    final int color = 0xff000000;
    final Paint paint = new Paint();
    final Rect rect = new Rect(0,0,bitmap.getWidth(), bitmap.getHeight());
    final RectF rectF = new RectF(rect);
    final float roundpx = 20;

    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(bitmap, rect, rect, paint);

    return output;
}

然后我像这样设置图像视图的比例类型:imageView.setScaleType(ScaleType.CENTER_CROP)

【问题讨论】:

  • 您找到解决方案了吗?

标签: android imageview android-imageview crop rounded-corners


【解决方案1】:

如果您确实使用 ImageView ,您可以为此使用 RoundedBitmapDrawableFactory 。示例:

class MainActivity : AppCompatActivity() {

    companion object {
        @JvmStatic
        fun getCircularDrawable(context: Context, bitmap: Bitmap): RoundedBitmapDrawable {
            val size = Math.min(bitmap.width, bitmap.height)
            val centerCropBitmap = ThumbnailUtils.extractThumbnail(bitmap, size, size)
            val roundedBitmapDrawable = RoundedBitmapDrawableFactory.create(context.resources, centerCropBitmap)
            roundedBitmapDrawable.isFilterBitmap = true
            roundedBitmapDrawable.setAntiAlias(true)
            roundedBitmapDrawable.isCircular = true
            return roundedBitmapDrawable
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        imageView.setImageDrawable(getCircularDrawable(this, BitmapFactory.decodeResource(resources, R.drawable.test)))
    }
}

结果:

缺点是我找不到只提供原始位图的方法,所以我必须先对其进行中心裁剪。我已经要求拥有这种能力here

【讨论】:

    【解决方案2】:

    如果你用 cardview 包装你的 imageview,你就实现了。

    <android.support.v7.widget.CardView 
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:card_view="http://schemas.android.com/apk/res-auto"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        card_view:cardCornerRadius="4dp"
        card_view:cardElevation="4dp"
        card_view:cardUseCompatPadding="true">
            <ImageView
                android:id="@+id/ivImage"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@drawable/your_image" />
    </android.support.v7.widget.CardView>
    

    【讨论】:

    • 这是一个相当不错的解决方案!请注意,如果您只想要圆角而没有阴影,请将 cardElevation 设置为 0 或不使用它。此外,现在在大多数情况下,您可能会忽略 cardUseCompatPadding(默认为 false)。
    • 非常简单有效的解决方案!我对不保持纵横比的复杂解决方案感到疯狂。另外,我使用了一个cardCornerRadius,它是圆形效果的布局大小的一半。
    • 图像周围的笔触怎么样?出于某种原因,当我尝试添加它时,我总是会得到一些剩余的像素(黑色或白色,或图像本身)。即使使用具有设置笔划能力的新MaterialCardView类也有这个问题:issuetracker.google.com/issues/112064791
    • 使其成为 cardview 的子级会增加加载时间,并且在 recyclerview 期间会滞后。
    【解决方案3】:

    试试这个:

    public class RoundedImageView extends ImageView {
    
    private Path mMaskPath;
    private Paint mMaskPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    private int mCornerRadius = 10;
    
    public RoundedImageView(Context context) {
        super(context);
    
        init();
    }
    
    public RoundedImageView(Context context, AttributeSet attributeSet) {
        super(context, attributeSet);
    
        init();
    }
    
    public RoundedImageView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    
        init();
    }
    
    private void init() {
        ViewCompat.setLayerType(this, ViewCompat.LAYER_TYPE_SOFTWARE, null);
        mMaskPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
    }
    
    
    public void setCornerRadius(int cornerRadius) {
        mCornerRadius = cornerRadius;
        generateMaskPath(getWidth(), getHeight());
        invalidate();
    }
    
    @Override
    protected void onSizeChanged(int w, int h, int oldW, int oldH) {
        super.onSizeChanged(w, h, oldW, oldH);
    
        if (w != oldW || h != oldH) {
            generateMaskPath(w, h);
        }
    }
    
    private void generateMaskPath(int w, int h) {
        mMaskPath = new Path();
        mMaskPath.addRoundRect(new RectF(0,0,w,h), mCornerRadius, mCornerRadius, Path.Direction.CW);
        mMaskPath.setFillType(Path.FillType.INVERSE_WINDING);
    }
    
    @Override
    protected void onDraw(Canvas canvas) {
        if(canvas.isOpaque()) { // If canvas is opaque, make it transparent
            canvas.saveLayerAlpha(0, 0, canvas.getWidth(), canvas.getHeight(), 255, Canvas.HAS_ALPHA_LAYER_SAVE_FLAG);
        }
    
        super.onDraw(canvas);
    
        if(mMaskPath != null) {
            canvas.drawPath(mMaskPath, mMaskPaint);
        }
    }
    

    <your.pack.name.RoundedImageView
                android:id="@+id/image_id"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:scaleType="centerCrop" />
    
    RoundedImageView  iconImage = (RoundedImageView )findViewById(R.id.image_id);
    iconImage.setImageBitmap(bitmap);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-16
      • 2014-02-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-28
      相关资源
      最近更新 更多