在Android中,ImageView默认是一个矩形。如何使它成为一个圆角矩形(剪辑我的位图的所有4个角为圆角矩形)在ImageView?
请注意,从2021年起,只需使用ShapeableImageView
在Android中,ImageView默认是一个矩形。如何使它成为一个圆角矩形(剪辑我的位图的所有4个角为圆角矩形)在ImageView?
请注意,从2021年起,只需使用ShapeableImageView
当前回答
这里要回答的问题是: 如何在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;
}
其他回答
最近,还有另一种方法——使用Glide的生成API。它需要一些初始的工作,但它给了你Glide所有的力量,以及做任何事情的灵活性,因为你重写了实际的代码,所以我认为从长远来看,这是一个很好的解决方案。另外,使用非常简单和整洁。
首先,设置Glide版本4+:
implementation 'com.github.bumptech.glide:glide:4.6.1'
annotationProcessor 'com.github.bumptech.glide:compiler:4.6.1'
然后创建Glid的app模块类来触发注释处理:
@GlideModule
public final class MyAppGlideModule extends AppGlideModule {}
然后创建实际工作的Glide扩展。你可以自定义它来做任何你想做的事情:
@GlideExtension
public class MyGlideExtension {
private MyGlideExtension() {}
@NonNull
@GlideOption
public static RequestOptions roundedCorners(RequestOptions options, @NonNull Context context, int cornerRadius) {
int px = Math.round(cornerRadius * (context.getResources().getDisplayMetrics().xdpi / DisplayMetrics.DENSITY_DEFAULT));
return options.transforms(new RoundedCorners(px));
}
}
添加这些文件之后,构建您的项目。
然后像这样在你的代码中使用它:
GlideApp.with(this)
.load(imageUrl)
.roundedCorners(getApplicationContext(), 5)
.into(imageView);
对于上面提到的乔治·沃尔特斯二世,我只是把他的答案扩展了一下,以支持不同的圆角。这可以进一步优化(一些目标矩形重叠),但不是很多。
我知道这个线程有点老了,但它是谷歌上关于如何在Android上圆角ImageViews的查询的顶级结果之一。
/**
* Use this method to scale a bitmap and give it specific rounded corners.
* @param context Context object used to ascertain display density.
* @param bitmap The original bitmap that will be scaled and have rounded corners applied to it.
* @param upperLeft Corner radius for upper left.
* @param upperRight Corner radius for upper right.
* @param lowerRight Corner radius for lower right.
* @param lowerLeft Corner radius for lower left.
* @param endWidth Width to which to scale original bitmap.
* @param endHeight Height to which to scale original bitmap.
* @return Scaled bitmap with rounded corners.
*/
public static Bitmap getRoundedCornerBitmap(Context context, Bitmap bitmap, float upperLeft,
float upperRight, float lowerRight, float lowerLeft, int endWidth,
int endHeight) {
float densityMultiplier = context.getResources().getDisplayMetrics().density;
// scale incoming bitmap to appropriate px size given arguments and display dpi
bitmap = Bitmap.createScaledBitmap(bitmap,
Math.round(endWidth * densityMultiplier),
Math.round(endHeight * densityMultiplier), true);
// create empty bitmap for drawing
Bitmap output = Bitmap.createBitmap(
Math.round(endWidth * densityMultiplier),
Math.round(endHeight * densityMultiplier), Config.ARGB_8888);
// get canvas for empty bitmap
Canvas canvas = new Canvas(output);
int width = canvas.getWidth();
int height = canvas.getHeight();
// scale the rounded corners appropriately given dpi
upperLeft *= densityMultiplier;
upperRight *= densityMultiplier;
lowerRight *= densityMultiplier;
lowerLeft *= densityMultiplier;
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(Color.WHITE);
// fill the canvas with transparency
canvas.drawARGB(0, 0, 0, 0);
// draw the rounded corners around the image rect. clockwise, starting in upper left.
canvas.drawCircle(upperLeft, upperLeft, upperLeft, paint);
canvas.drawCircle(width - upperRight, upperRight, upperRight, paint);
canvas.drawCircle(width - lowerRight, height - lowerRight, lowerRight, paint);
canvas.drawCircle(lowerLeft, height - lowerLeft, lowerLeft, paint);
// fill in all the gaps between circles. clockwise, starting at top.
RectF rectT = new RectF(upperLeft, 0, width - upperRight, height / 2);
RectF rectR = new RectF(width / 2, upperRight, width, height - lowerRight);
RectF rectB = new RectF(lowerLeft, height / 2, width - lowerRight, height);
RectF rectL = new RectF(0, upperLeft, width / 2, height - lowerLeft);
canvas.drawRect(rectT, paint);
canvas.drawRect(rectR, paint);
canvas.drawRect(rectB, paint);
canvas.drawRect(rectL, paint);
// set up the rect for the image
Rect imageRect = new Rect(0, 0, width, height);
// set up paint object such that it only paints on Color.WHITE
paint.setXfermode(new AvoidXfermode(Color.WHITE, 255, AvoidXfermode.Mode.TARGET));
// draw resized bitmap onto imageRect in canvas, using paint as configured above
canvas.drawBitmap(bitmap, imageRect, imageRect, paint);
return output;
}
有一个很酷的库可以让你塑造imageviews。
这里有一个例子:
<com.github.siyamed.shapeimageview.mask.PorterShapeImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:siShape="@drawable/shape_rounded_rectangle"
android:src="@drawable/neo"
app:siSquare="true"/>
形状定义:
<shape android:shape="rectangle" xmlns:android="http://schemas.android.com/apk/res/android">
<corners
android:topLeftRadius="18dp"
android:topRightRadius="18dp"
android:bottomLeftRadius="18dp"
android:bottomRightRadius="18dp" />
<solid android:color="@color/black" />
</shape>
结果:
如果你们中有人面临这个问题
大多数情况下,你使用的是Android Studio。由于图像大小的调整和所有在Android工作室,你可能会遇到这个问题。解决这个问题的一个简单方法是减小drawCircle()中的圆的半径。在我的情况下,我使用这个修复
使用画布。drawCircle(100,100,90, paint);而不是帆布。drawCircle(100,100,100, paint);这绝对能解决你的问题。
下面是最终编辑的代码:-
public class Profile extends ActionBarActivity {
TextView username;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.profile);
username= (TextView) findViewById(R.id.txt);
String recievedusername=getIntent().getExtras().getString("toname");
username.setText(recievedusername);
Bitmap bm = BitmapFactory.decodeResource(getResources(),
R.mipmap.gomez);
Bitmap resizedBitmap = Bitmap.createScaledBitmap(bm, 200,200, false);
Bitmap conv_bm=getCircleBitmap(resizedBitmap,100);
// set circle bitmap
ImageView mImage = (ImageView) findViewById(R.id.profile_image);
mImage.setImageBitmap(conv_bm);
// TODO Auto-generated method stub
}
private Bitmap getCircleBitmap(Bitmap bitmap , int pixels) {
final Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight(), Bitmap.Config.ARGB_8888);
final Canvas canvas = new Canvas(output);
final int color = 0xff424242;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, bitmap.getWidth(),bitmap.getHeight());
final RectF rectF = new RectF(rect);
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawCircle(100,100, 90, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
bitmap.recycle();
return output;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_apploud, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_addnew) {
Intent i;
i=new Intent(Profile.this,ApplaudSomeone.class);
startActivity(i);
return true;
}
return super.onOptionsItemSelected(item);
}
}
这不是确切的答案,但它是一个类似的解决方案。它可能会帮助那些和我有同样遭遇的人。
我的图像是一个应用程序logo,它的背景是透明的,我正在应用XML渐变作为图像背景。我在imageView中添加了必要的padding/margin,然后添加了这个作为我的背景:
<?xml version="1.0" encoding="utf-8"?>
<!-- This file defines the gradient used on the background of the main activity. -->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<gradient
android:type="linear"
android:startColor="@color/app_color_light_background"
android:endColor="@color/app_color_disabled"
android:angle="90" />
<!-- Round the top corners. -->
<corners
android:topLeftRadius="@dimen/radius_small"
android:topRightRadius="@dimen/radius_small" />
</shape>
</item>
</selector>