在Android中,ImageView默认是一个矩形。如何使它成为一个圆角矩形(剪辑我的位图的所有4个角为圆角矩形)在ImageView?
请注意,从2021年起,只需使用ShapeableImageView
在Android中,ImageView默认是一个矩形。如何使它成为一个圆角矩形(剪辑我的位图的所有4个角为圆角矩形)在ImageView?
请注意,从2021年起,只需使用ShapeableImageView
当前回答
罗曼盖伊就在那里。
缩小版如下。
Bitmap bitmap = ((BitmapDrawable) getResources().getDrawable(R.drawable.image)).getBitmap();
Bitmap bitmapRounded = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), bitmap.getConfig());
Canvas canvas = new Canvas(bitmapRounded);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setShader(new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
canvas.drawRoundRect((new RectF(0.0f, 0.0f, bitmap.getWidth(), bitmap.getHeight())), 10, 10, paint);
imageView.setImageBitmap(bitmapRounded);
其他回答
这里要回答的问题是: 如何在Android中创建一个圆形ImageView ?
public static Bitmap getRoundBitmap(Bitmap bitmap) {
int min = Math.min(bitmap.getWidth(), bitmap.getHeight());
Bitmap bitmapRounded = Bitmap.createBitmap(min, min, bitmap.getConfig());
Canvas canvas = new Canvas(bitmapRounded);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setShader(new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
canvas.drawRoundRect((new RectF(0.0f, 0.0f, min, min)), min/2, min/2, paint);
return bitmapRounded;
}
这种纯xml解决方案对我来说已经足够好了。http://www.techrepublic.com/article/pro-tip-round-corners-on-an-android-imageview-with-this-hack/
EDIT
以下是简单的答案:
在/res/drawable文件夹中,创建一个frame.xml文件。在其中,我们定义了一个具有圆角和透明中心的简单矩形。
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<solid android:color="#00ffffff" />
<padding android:left="6dp"
android:top="6dp"
android:right="6dp"
android:bottom="6dp" />
<corners android:radius="12dp" />
<stroke android:width="6dp" android:color="#ffffffff" />
</shape>
在你的布局文件中,你添加了一个线性布局,它包含一个标准的ImageView,以及一个嵌套的framayout。FrameLayout使用填充和自定义drawable来提供圆角的错觉。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_gravity="center"
android:gravity="center"
android:background="#ffffffff">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="6dp"
android:src="@drawable/tr"/>
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="6dp"
android:src="@drawable/tr"/>
<ImageView
android:src="@drawable/frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
</LinearLayout>
芬兰湾的科特林版:
@GlideExtension
object GamersGeekGlideExtension {
@NonNull
@JvmStatic
@GlideOption
fun roundedCorners(options: BaseRequestOptions<*>, context: Context, cornerRadius: Int): BaseRequestOptions<*> {
val px =
(cornerRadius * (context.resources.displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT)).roundToInt()
return options.transforms(RoundedCorners(px))
}
}
注意:Glide扩展现在需要BaseRequestOptions而不是RequestOptions。此外,它与@Sir Codesalot答案在kotlin中转换的函数相同。
你可以在你的布局中只使用ImageView,使用滑动,你可以使用这个方法应用圆角。
首先在你的gradle里写上,
compile 'com.github.bumptech.glide:glide:3.7.0'
对于有圆角的图像,
public void loadImageWithCorners(String url, ImageView view) {
Glide.with(context)
.load(url)
.asBitmap()
.centerCrop()
.placeholder(R.color.gray)
.error(R.color.gray)
.diskCacheStrategy(DiskCacheStrategy.SOURCE)
.into(new BitmapImageViewTarget(view) {
@Override
protected void setResource(Bitmap resource) {
RoundedBitmapDrawable circularBitmapDrawable =
RoundedBitmapDrawableFactory.create(context.getResources(), resource);
circularBitmapDrawable.setCornerRadius(32.0f); // radius for corners
view.setImageDrawable(circularBitmapDrawable);
}
});
}
调用方法:
loadImageWithCorners("your url","your imageview");
如果你不希望边框影响图像,使用这个类。不幸的是,我没有找到任何方法来绘制画布上的透明区域来到onDraw()。这里创建了一个新的位图它是画在一个真实的画布上的。
如果您想要创建一个消失的边界,该视图非常有用。如果你将borderWidth设置为0,边框将会消失,图像仍然保持圆角,就像边界一样。也就是说,它看起来就像边界完全由图像边缘绘制。
import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.PorterDuff
import android.graphics.PorterDuffXfermode
import android.graphics.RectF
import android.util.AttributeSet
import androidx.appcompat.widget.AppCompatImageView
class RoundedImageViewWithBorder @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0) : AppCompatImageView(context, attrs, defStyleAttr) {
var borderColor: Int = 0
set(value) {
invalidate()
field = value
}
var borderWidth: Int = 0
set(value) {
invalidate()
field = value
}
var cornerRadius: Float = 0f
set(value) {
invalidate()
field = value
}
private var bitmapForDraw: Bitmap? = null
private var canvasForDraw: Canvas? = null
private val transparentPaint = Paint().apply {
isAntiAlias = true
color = Color.TRANSPARENT
style = Paint.Style.STROKE
xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC)
}
private val borderPaint = Paint().apply {
isAntiAlias = true
style = Paint.Style.STROKE
}
private val transparentAreaRect = RectF()
private val borderRect = RectF()
init {
val typedArray = context.obtainStyledAttributes(attrs, R.styleable.RoundedImageViewWithBorder)
try {
borderWidth = typedArray.getDimensionPixelSize(R.styleable.RoundedImageViewWithBorder_border_width, 0)
borderColor = typedArray.getColor(R.styleable.RoundedImageViewWithBorder_border_color, 0)
cornerRadius = typedArray.getDimensionPixelSize(R.styleable.RoundedImageViewWithBorder_corner_radius, 0).toFloat()
} finally {
typedArray.recycle()
}
}
@SuppressLint("CanvasSize", "DrawAllocation")
override fun onDraw(canvas: Canvas) {
if (canvas.height <=0 || canvas.width <=0) {
return
}
if (canvasForDraw?.height != canvas.height || canvasForDraw?.width != canvas.width) {
val newBitmap = Bitmap.createBitmap(canvas.width, canvas.height, Bitmap.Config.ARGB_8888)
bitmapForDraw = newBitmap
canvasForDraw = Canvas(newBitmap)
}
bitmapForDraw?.eraseColor(Color.TRANSPARENT)
// Draw existing content
super.onDraw(canvasForDraw)
if (borderWidth > 0) {
canvasForDraw?.let { drawWithBorder(it) }
} else {
canvasForDraw?.let { drawWithoutBorder(it) }
}
// Draw everything on real canvas
bitmapForDraw?.let { canvas.drawBitmap(it, 0f, 0f, null) }
}
private fun drawWithBorder(canvas: Canvas) {
// Draw transparent area
transparentPaint.strokeWidth = borderWidth.toFloat() * 4
transparentAreaRect.apply {
left = -borderWidth.toFloat() * 1.5f
top = -borderWidth.toFloat() * 1.5f
right = canvas.width.toFloat() + borderWidth.toFloat() * 1.5f
bottom = canvas.height.toFloat() + borderWidth.toFloat() * 1.5f
}
canvasForDraw?.drawRoundRect(transparentAreaRect, borderWidth.toFloat() * 2 + cornerRadius, borderWidth.toFloat() * 2 + cornerRadius, transparentPaint)
// Draw border
borderPaint.color = borderColor
borderPaint.strokeWidth = borderWidth.toFloat()
borderRect.apply {
left = borderWidth.toFloat() / 2
top = borderWidth.toFloat() / 2
right = canvas.width.toFloat() - borderWidth.toFloat() / 2
bottom = canvas.height.toFloat() - borderWidth.toFloat() / 2
}
canvas.drawRoundRect(borderRect, cornerRadius - borderWidth.toFloat() / 2, cornerRadius - borderWidth.toFloat() / 2, borderPaint)
}
private fun drawWithoutBorder(canvas: Canvas) {
// Draw transparent area
transparentPaint.strokeWidth = cornerRadius * 4
transparentAreaRect.apply {
left = -cornerRadius * 2
top = -cornerRadius * 2
right = canvas.width.toFloat() + cornerRadius * 2
bottom = canvas.height.toFloat() + cornerRadius * 2
}
canvasForDraw?.drawRoundRect(transparentAreaRect, cornerRadius * 3, cornerRadius * 3, transparentPaint)
}
}
值:
<declare-styleable name="RoundedImageViewWithBorder">
<attr name="corner_radius" format="dimension|string" />
<attr name="border_width" format="dimension|reference" />
<attr name="border_color" format="color|reference" />
</declare-styleable>