Sous Android, un ImageView est un rectangle par défaut. Comment puis-je en faire un rectangle arrondi (couper les 4 coins de mon bitmap pour qu'ils soient des rectangles arrondis) dans ImageView?
La réponse est assez tardive, mais si vous recherchez une solution, vous pouvez utiliser le code suivant pour arrondir manuellement les angles de vos images.
Ce n'est pas mon code, mais je l'ai utilisé et cela fonctionne à merveille. Je l'ai utilisé en tant qu'assistant dans une classe ImageHelper et l'ai étendu un peu pour indiquer la quantité de dégradé dont j'ai besoin pour une image donnée.
Le code final ressemble à ceci:
package com.company.app.utils;
import Android.graphics.Bitmap;
import Android.graphics.Canvas;
import Android.graphics.Paint;
import Android.graphics.PorterDuffXfermode;
import Android.graphics.Rect;
import Android.graphics.RectF;
import Android.graphics.Bitmap.Config;
import Android.graphics.PorterDuff.Mode;
public class ImageHelper {
public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, int pixels) {
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap
.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, bitmap.getWidth(), bitmap.getHeight());
final RectF rectF = new RectF(rect);
final float roundPx = pixels;
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;
}
}
J'espère que cela aide quelqu'un!
Alors que la réponse ci-dessus fonctionne, Romain Guy (un développeur principal pour Android) montre une meilleure méthode dans son blog qui utilise moins de mémoire en utilisant un shader ne créant pas de copie du bitmap. L'essentiel général de la fonctionnalité est ici:
BitmapShader shader;
shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
Paint paint = new Paint();
Paint.setAntiAlias(true);
Paint.setShader(shader);
RectF rect = new RectF(0.0f, 0.0f, width, height);
// rect contains the bounds of the shape
// radius is the radius in pixels of the rounded corners
// Paint contains the shader that will texture the shape
canvas.drawRoundRect(rect, radius, radius, Paint);
Les avantages de cette méthode par rapport aux autres méthodes sont les suivantes:
J'ai créé un RoundedImageView basé sur ce code qui englobe cette logique dans un ImageView et ajoute le support approprié ScaleType
et une bordure arrondie optionnelle.
Un autre moyen simple consiste à utiliser un CardView avec le rayon de coin et un ImageView à l'intérieur:
<Android.support.v7.widget.CardView
Android:layout_width="match_parent"
Android:layout_height="match_parent"
app:cardCornerRadius="8dp"
Android:layout_margin="5dp"
Android:elevation="10dp">
<ImageView
Android:id="@+id/roundedImageView"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:src="@drawable/image"
Android:background="@color/white"
Android:scaleType="centerCrop"
/>
</Android.support.v7.widget.CardView>
Dans la v21 de la bibliothèque Support, il existe maintenant une solution à cela: elle s'appelle RoundedBitmapDrawable .
C'est fondamentalement comme un Drawable normal sauf que vous lui donnez un rayon de coin pour le découpage avec:
setCornerRadius(float cornerRadius)
Donc, en commençant par Bitmap src
et une cible ImageView
, cela ressemblerait à ceci:
RoundedBitmapDrawable dr = RoundedBitmapDrawableFactory.create(res, src);
dr.setCornerRadius(cornerRadius);
imageView.setImageDrawable(dr);
Le découpage en formes arrondies a été ajouté à la classe View
dans API 21.
Faites juste ceci:
res/drawable/round_outline.xml
<shape xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:shape="rectangle">
<corners Android:radius="10dp" />
...
</shape>
Android:background="@drawable/round_outline"
Android:clipToOutline="true"
Malheureusement, il y a un bogue et cet attribut XML n'est pas reconnu. Heureusement, nous pouvons toujours configurer la découpe en Java:
ImageView.setClipToOutline(true)
Voici à quoi cela ressemblera:
Remarque:
Cette méthode fonctionne pour toute forme dessiné (pas seulement arrondie). Il visionnera ImageView selon le contour de forme défini dans votre fichier XML Drawable.
Note spéciale sur ImageViews
setClipToOutline()
ne fonctionne que lorsque l'arrière-plan de la vue est défini sur une forme pouvant être dessinée. Si cette forme d'arrière-plan existe, View considère le contour de la forme comme des bordures à des fins de découpage et d'ombrage.
Cela signifie que si vous souhaitez utiliser setClipToOutline()
pour arrondir les angles d'un ImageView, votre image doit être définie avec Android:src
au lieu de Android:background
(car l'arrière-plan doit être défini sur votre forme arrondie). Si vous DEVEZ utiliser l’arrière-plan pour définir votre image au lieu de src, vous pouvez utiliser cette solution de contournement:
J'ai trouvé que les deux méthodes étaient très utiles pour trouver une solution efficace. Voici ma version composite, indépendante du pixel, qui vous permet d’avoir des coins carrés, le reste des coins ayant le même rayon (ce qui est le cas d’utilisation habituel). Grâce aux deux solutions ci-dessus:
public static Bitmap getRoundedCornerBitmap(Context context, Bitmap input, int pixels , int w , int h , boolean squareTL, boolean squareTR, boolean squareBL, boolean squareBR ) {
Bitmap output = Bitmap.createBitmap(w, h, Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final float densityMultiplier = context.getResources().getDisplayMetrics().density;
final int color = 0xff424242;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, w, h);
final RectF rectF = new RectF(rect);
//make sure that our rounded corner is scaled appropriately
final float roundPx = pixels*densityMultiplier;
Paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
Paint.setColor(color);
canvas.drawRoundRect(rectF, roundPx, roundPx, Paint);
//draw rectangles over the corners we want to be square
if (squareTL ){
canvas.drawRect(0, h/2, w/2, h, Paint);
}
if (squareTR ){
canvas.drawRect(w/2, h/2, w, h, Paint);
}
if (squareBL ){
canvas.drawRect(0, 0, w/2, h/2, Paint);
}
if (squareBR ){
canvas.drawRect(w/2, 0, w, h/2, Paint);
}
Paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(input, 0,0, Paint);
return output;
}
De plus, j'ai écrasé ImageView pour l'inclure afin de pouvoir le définir en xml . Vous voudrez peut-être ajouter une partie de la logique que le super appel crée ici, mais je l'ai commenté car ce n'est pas utile dans mon cas .
@Override
protected void onDraw(Canvas canvas) {
//super.onDraw(canvas);
Drawable drawable = getDrawable();
Bitmap b = ((BitmapDrawable)drawable).getBitmap() ;
Bitmap bitmap = b.copy(Bitmap.Config.ARGB_8888, true);
int w = getWidth(), h = getHeight();
Bitmap roundBitmap = CropImageView.getRoundedCornerBitmap( getContext(), bitmap,10 , w, h , true, false,true, false);
canvas.drawBitmap(roundBitmap, 0,0 , null);
}
J'espère que cela t'aides!
J'ai fait par Custom ImageView:
public class RoundRectCornerImageView extends ImageView {
private float radius = 18.0f;
private Path path;
private RectF rect;
public RoundRectCornerImageView(Context context) {
super(context);
init();
}
public RoundRectCornerImageView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public RoundRectCornerImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
path = new Path();
}
@Override
protected void onDraw(Canvas canvas) {
rect = new RectF(0, 0, this.getWidth(), this.getHeight());
path.addRoundRect(rect, radius, radius, Path.Direction.CW);
canvas.clipPath(path);
super.onDraw(canvas);
}
}
Comment utiliser:
<com.mypackage.RoundRectCornerImageView
Android:id="@+id/imageView"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:background="@drawable/image"
Android:scaleType="fitXY" />
Sortie:
J'espère que cela vous aiderait.
Image arrondie Utilisation de ImageLoader
ici
Créer DisplayImageOptions
:
DisplayImageOptions options = new DisplayImageOptions.Builder()
// this will make circle, pass the width of image
.displayer(new RoundedBitmapDisplayer(getResources().getDimensionPixelSize(R.dimen.image_dimen_menu)))
.cacheOnDisc(true)
.build();
imageLoader.displayImage(url_for_image,ImageView,options);
Ou vous pouvez utiliser la bibliothèque Picasso
de Square.
Picasso.with(mContext)
.load(com.app.utility.Constants.BASE_URL+b.image)
.placeholder(R.drawable.profile)
.error(R.drawable.profile)
.transform(new RoundedTransformation(50, 4))
.resizeDimen(R.dimen.list_detail_image_size, R.dimen.list_detail_image_size)
.centerCrop()
.into(v.im_user);
vous pouvez télécharger le fichier RoundedTransformation ici ici
Comme toutes les réponses semblaient trop compliquées pour moi, rien que pour les angles arrondis, j’ai pensé à une autre solution qu’il vaut la peine de partager, à l’aide de XML, au cas où vous auriez un peu de place autour de l’image:
Créez une forme bordée avec un contenu transparent comme ceci:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:shape="rectangle">
<corners
Android:radius="30dp" />
<stroke
Android:color="#ffffffff"
Android:width="10dp" />
</shape>
Ensuite, dans un RelativeLayout, vous pouvez d'abord placer votre image, puis au même endroit au-dessus de la forme avec un autre ImageView. La forme de la couverture doit avoir une taille supérieure à celle de la largeur de la bordure. Veillez à prendre un rayon de coin plus grand, car le rayon extérieur est défini, mais le rayon intérieur recouvre votre image.
J'espère que ça aide aussi quelqu'un.
Edit selon CQM demande l'exemple de présentation relative:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="match_parent"
Android:layout_height="match_parent" >
<ImageView
Android:id="@+id/imageToShow"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_alignBottom="@+id/imgCorners"
Android:layout_alignLeft="@+id/imgCorners"
Android:layout_alignRight="@+id/imgCorners"
Android:layout_alignTop="@+id/imgCorners"
Android:background="#ffffff"
Android:contentDescription="@string/desc"
Android:padding="5dp"
Android:scaleType="centerCrop" />
<ImageView
Android:id="@+id/imgCorners"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:adjustViewBounds="true"
Android:contentDescription="@string/desc"
Android:src="@drawable/corners_white" />
</RelativeLayout>
Mon implémentation de ImageView avec un widget coins arrondis, qui (vers le haut || vers le haut) redimensionne l'image aux dimensions requises Il utilise la forme de code CaspNZ.
public class ImageViewRounded extends ImageView {
public ImageViewRounded(Context context) {
super(context);
}
public ImageViewRounded(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ImageViewRounded(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onDraw(Canvas canvas) {
BitmapDrawable drawable = (BitmapDrawable) getDrawable();
if (drawable == null) {
return;
}
if (getWidth() == 0 || getHeight() == 0) {
return;
}
Bitmap fullSizeBitmap = drawable.getBitmap();
int scaledWidth = getMeasuredWidth();
int scaledHeight = getMeasuredHeight();
Bitmap mScaledBitmap;
if (scaledWidth == fullSizeBitmap.getWidth() && scaledHeight == fullSizeBitmap.getHeight()) {
mScaledBitmap = fullSizeBitmap;
} else {
mScaledBitmap = Bitmap.createScaledBitmap(fullSizeBitmap, scaledWidth, scaledHeight, true /* filter */);
}
Bitmap roundBitmap = ImageUtilities.getRoundedCornerBitmap(getContext(), mScaledBitmap, 5, scaledWidth, scaledHeight,
false, false, false, false);
canvas.drawBitmap(roundBitmap, 0, 0, null);
}
}
Récemment, il existe un autre moyen - en utilisant l'API générée de Glide . Cela prend un peu de travail initial mais vous donne ensuite toute la puissance de Glide avec la possibilité de faire n'importe quoi parce que vous écrasez le code lui-même, je pense donc que c'est une bonne solution à long terme. De plus, l'utilisation est très simple et soignée.
Premièrement, setup Glide version 4+:
implementation 'com.github.bumptech.glide:glide:4.6.1'
annotationProcessor 'com.github.bumptech.glide:compiler:4.6.1'
Créez ensuite la classe de module d'application de Glid pour déclencher le traitement des annotations:
@GlideModule
public final class MyAppGlideModule extends AppGlideModule {}
Créez ensuite l’extension Glide qui effectue le travail. Vous pouvez le personnaliser pour faire ce que vous voulez:
@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));
}
}
Après avoir ajouté ces fichiers, construisez votre projet.
Puis utilisez-le dans votre code comme ceci:
GlideApp.with(this)
.load(imageUrl)
.roundedCorners(getApplicationContext(), 5)
.into(imageView);
Vous devriez agrandir ImageView
et dessiner votre propre rectangle arrondi.
Si vous souhaitez un cadre autour de l'image, vous pouvez également superposer le cadre arrondi au-dessus de la vue de l'image dans la présentation.
[edit] Superposez le cadre sur l'image d'origine, en utilisant une variable FrameLayout
par exemple. Le premier élément de la FrameLayout
sera l'image que vous voulez afficher arrondie. Ajoutez ensuite une autre ImageView
avec le cadre. La seconde ImageView
sera affichée par-dessus la ImageView
d'origine et ainsi Android en tirera le contenu au-dessus de la ImageView
originale.
Pour les accessoires de George Walters II ci-dessus, je viens de prendre sa réponse et de l’étendre un peu pour supporter les arrondis individuels différemment. Cela pourrait être optimisé un peu plus loin (certains des objectifs cibles se chevauchent), mais pas beaucoup.
Je sais que ce fil est un peu vieux, mais c’est l’un des meilleurs résultats pour les requêtes sur Google relatives à la manière de contourner les angles d’ImageViews sur Android.
/**
* 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;
}
Il existe une bibliothèque cool qui vous permet de façonner des images.
Voici un exemple:
<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"/>
Définition de la forme:
<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>
Résultat:
Romain Guy est là.
Version modifiée comme suit.
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);
Cette solution XML pure était assez bonne dans mon cas. http://www.techrepublic.com/article/pro-tip-round-corners-on-an-Android-imageview-with-this-hack/
MODIFIER
Voici la réponse en quelques mots:
Dans le dossier/res/drawable, créez un fichier frame.xml. On y définit un rectangle simple avec des angles arrondis et un centre transparent.
<?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>
Dans votre fichier de présentation, vous ajoutez un LinearLayout contenant un ImageView standard, ainsi qu'un FrameLayout imbriqué. Le FrameLayout utilise un rembourrage et un dessin personnalisable pour donner l’illusion de coins arrondis.
<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>
Ce qui suit crée un objet de mise en page de rectangle arrondi qui dessine un rectangle arrondi autour des objets enfant qui y sont placés. Il montre également comment créer des vues et des mises en forme par programme sans utiliser les fichiers XML de mise en page.
package Android.example;
import Android.app.Activity;
import Android.graphics.Color;
import Android.os.Bundle;
import Android.util.DisplayMetrics;
import Android.util.TypedValue;
import Android.view.ViewGroup.LayoutParams;
import Android.widget.LinearLayout;
import Android.widget.TextView;
public class MessageScreen extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
int mainBackgroundColor = Color.parseColor("#2E8B57");
int labelTextColor = Color.parseColor("#FF4500");
int messageBackgroundColor = Color.parseColor("#3300FF");
int messageTextColor = Color.parseColor("#FFFF00");
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
float density = metrics.density;
int minMarginSize = Math.round(density * 8);
int paddingSize = minMarginSize * 2;
int maxMarginSize = minMarginSize * 4;
TextView label = new TextView(this);
/*
* The LayoutParams are instructions to the Layout that will contain the
* View for laying out the View, so you need to use the LayoutParams of
* the Layout that will contain the View.
*/
LinearLayout.LayoutParams labelLayoutParams = new LinearLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
label.setLayoutParams(labelLayoutParams);
label.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18);
label.setPadding(paddingSize, paddingSize, paddingSize, paddingSize);
label.setText(R.string.title);
label.setTextColor(labelTextColor);
TextView message = new TextView(this);
RoundedRectangle.LayoutParams messageLayoutParams = new RoundedRectangle.LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
/*
* This is one of the calls must made to force a ViewGroup to call its
* draw method instead of just calling the draw method of its children.
* This tells the RoundedRectangle to put some extra space around the
* View.
*/
messageLayoutParams.setMargins(minMarginSize, paddingSize,
minMarginSize, maxMarginSize);
message.setLayoutParams(messageLayoutParams);
message.setTextSize(TypedValue.COMPLEX_UNIT_SP, paddingSize);
message.setText(R.string.message);
message.setTextColor(messageTextColor);
message.setBackgroundColor(messageBackgroundColor);
RoundedRectangle messageContainer = new RoundedRectangle(this);
LinearLayout.LayoutParams messageContainerLayoutParams = new LinearLayout.LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
messageContainerLayoutParams.setMargins(paddingSize, 0, paddingSize, 0);
messageContainer.setLayoutParams(messageContainerLayoutParams);
messageContainer.setOrientation(LinearLayout.VERTICAL);
/*
* This is one of the calls must made to force a ViewGroup to call its
* draw method instead of just calling the draw method of its children.
* This tells the RoundedRectangle to color the the exta space that was
* put around the View as well as the View. This is exterior color of
* the RoundedRectangle.
*/
messageContainer.setBackgroundColor(mainBackgroundColor);
/*
* This is one of the calls must made to force a ViewGroup to call its
* draw method instead of just calling the draw method of its children.
* This is the interior color of the RoundedRectangle. It must be
* different than the exterior color of the RoundedRectangle or the
* RoundedRectangle will not call its draw method.
*/
messageContainer.setInteriorColor(messageBackgroundColor);
// Add the message to the RoundedRectangle.
messageContainer.addView(message);
//
LinearLayout main = new LinearLayout(this);
LinearLayout.LayoutParams mainLayoutParams = new LinearLayout.LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
main.setLayoutParams(mainLayoutParams);
main.setOrientation(LinearLayout.VERTICAL);
main.setBackgroundColor(mainBackgroundColor);
main.addView(label);
main.addView(messageContainer);
setContentView(main);
}
}
La classe d'objet de mise en forme RoundedRectangle est telle que définie ici:
/**
* A LinearLayout that draws a rounded rectangle around the child View that was added to it.
*/
package Android.example;
import Android.app.Activity;
import Android.content.Context;
import Android.graphics.Canvas;
import Android.graphics.Paint;
import Android.graphics.Rect;
import Android.graphics.RectF;
import Android.util.AttributeSet;
import Android.util.DisplayMetrics;
import Android.widget.LinearLayout;
/**
* A LinearLayout that has rounded corners instead of square corners.
*
* @author Danny Remington
*
* @see LinearLayout
*
*/
public class RoundedRectangle extends LinearLayout {
private int mInteriorColor;
public RoundedRectangle(Context p_context) {
super(p_context);
}
public RoundedRectangle(Context p_context, AttributeSet attributeSet) {
super(p_context, attributeSet);
}
// Listener for the onDraw event that occurs when the Layout is drawn.
protected void onDraw(Canvas canvas) {
Rect rect = new Rect(0, 0, getWidth(), getHeight());
RectF rectF = new RectF(rect);
DisplayMetrics metrics = new DisplayMetrics();
Activity activity = (Activity) getContext();
activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
float density = metrics.density;
int arcSize = Math.round(density * 10);
Paint paint = new Paint();
Paint.setColor(mInteriorColor);
canvas.drawRoundRect(rectF, arcSize, arcSize, Paint);
}
/**
* Set the background color to use inside the RoundedRectangle.
*
* @param Primitive int - The color inside the rounded rectangle.
*/
public void setInteriorColor(int interiorColor) {
mInteriorColor = interiorColor;
}
/**
* Get the background color used inside the RoundedRectangle.
*
* @return Primitive int - The color inside the rounded rectangle.
*/
public int getInteriorColor() {
return mInteriorColor;
}
}
pourquoi ne pas couper dans draw ()?
Voici ma solution:
code:
public class RoundRelativeLayout extends RelativeLayout {
private final float radius;
public RoundRelativeLayout(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray attrArray = context.obtainStyledAttributes(attrs,
R.styleable.RoundRelativeLayout);
radius = attrArray.getDimension(
R.styleable.RoundRelativeLayout_radius, 0);
}
private boolean isPathValid;
private final Path path = new Path();
private Path getRoundRectPath() {
if (isPathValid) {
return path;
}
path.reset();
int width = getWidth();
int height = getHeight();
RectF bounds = new RectF(0, 0, width, height);
path.addRoundRect(bounds, radius, radius, Direction.CCW);
isPathValid = true;
return path;
}
@Override
protected void dispatchDraw(Canvas canvas) {
canvas.clipPath(getRoundRectPath());
super.dispatchDraw(canvas);
}
@Override
public void draw(Canvas canvas) {
canvas.clipPath(getRoundRectPath());
super.draw(canvas);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int oldWidth = getMeasuredWidth();
int oldHeight = getMeasuredHeight();
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int newWidth = getMeasuredWidth();
int newHeight = getMeasuredHeight();
if (newWidth != oldWidth || newHeight != oldHeight) {
isPathValid = false;
}
}
}
Appliquez une forme à votre imageView
comme ci-dessous:
<shape xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:shape="rectangle" >
<solid Android:color="#faf5e6" />
<stroke
Android:width="1dp"
Android:color="#808080" />
<corners Android:radius="15dp" />
<padding
Android:bottom="5dp"
Android:left="5dp"
Android:right="5dp"
Android:top="5dp" />
</shape>
cela peut vous être utile, mon ami.
Merci beaucoup d'avoir d'abord répondu. Voici la version modifiée pour convertir une image rectangulaire en une image carrée (et arrondie) et la couleur de remplissage est passée en paramètre.
public static Bitmap getRoundedBitmap(Bitmap bitmap, int pixels, int color) {
Bitmap inpBitmap = bitmap;
int width = 0;
int height = 0;
width = inpBitmap.getWidth();
height = inpBitmap.getHeight();
if (width <= height) {
height = width;
} else {
width = height;
}
Bitmap output = Bitmap.createBitmap(width, height, Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, width, height);
final RectF rectF = new RectF(rect);
final float roundPx = pixels;
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(inpBitmap, rect, rect, Paint);
return output;
}
Une solution xml rapide -
<Android.support.v7.widget.CardView
Android:layout_width="40dp"
Android:layout_height="40dp"
app:cardElevation="0dp"
app:cardCornerRadius="4dp">
<ImageView
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:id="@+id/rounded_user_image"
Android:scaleType="fitXY"/>
</Android.support.v7.widget.CardView>
Vous pouvez définir la largeur, la hauteur et le rayon souhaités sur CardView et scaleType sur ImageView.
Voici un exemple simple remplaçant imageView, que vous pouvez également utiliser dans le concepteur de modèle pour obtenir un aperçu.
public class RoundedImageView extends ImageView {
public RoundedImageView(Context context) {
super(context);
}
public RoundedImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public RoundedImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@TargetApi(Build.VERSION_CODES.Lollipop)
public RoundedImageView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
public void setImageDrawable(Drawable drawable) {
float radius = 0.1f;
Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
RoundedBitmapDrawable rid = RoundedBitmapDrawableFactory.create(getResources(), bitmap);
rid.setCornerRadius(bitmap.getWidth() * radius);
super.setImageDrawable(rid);
}
}
Ceci est une solution rapide. Le rayon est utilisé à tous les coins et est basé sur un pourcentage de largeur de bitmap.
Je viens de remplacer setImageDrawable
et d’utiliser la méthode de support technique v4 pour les images bitmap arrondies.
Usage:
<com.example.widgets.RoundedImageView
Android:layout_width="39dp"
Android:layout_height="39dp"
Android:src="@drawable/your_drawable" />
Prévisualisation avec imageView et imageView personnalisé:
si votre image est sur Internet, le meilleur moyen consiste à utiliser glide et RoundedBitmapDrawableFactory
(à partir de l'API 21 - mais disponible dans la bibliothèque de support technique) comme suit:
Glide.with(ctx).load(url).asBitmap().centerCrop().into(new BitmapImageViewTarget(imageView) {
@Override
protected void setResource(Bitmap res) {
RoundedBitmapDrawable bitmapDrawable =
RoundedBitmapDrawableFactory.create(ctx.getResources(), res);
bitmapDrawable.setCircular(true);//comment this line and uncomment the next line if you dont want it fully cricular
//circularBitmapDrawable.setCornerRadius(cornerRadius);
imageView.setImageDrawable(bitmapDrawable);
}
});
vous pouvez utiliser uniquement ImageView
dans votre présentation et utiliser glide
, vous pouvez appliquer des angles arrondis à l'aide de cette méthode.
premier dans votre note,
compile 'com.github.bumptech.glide:glide:3.7.0'
pour les images aux coins arrondis,
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);
}
});
}
méthode d'appel:
loadImageWithCorners("your url","your imageview");
Si vous utilisez Glide Library, cela serait utile:
Glide.with(getApplicationContext())
.load(image_url)
.asBitmap()
.centerCrop()
.into(new BitmapImageViewTarget(imageView) {
@Override
protected void setResource(Bitmap resource) {
RoundedBitmapDrawable circularBitmapDrawable =
RoundedBitmapDrawableFactory.create(getApplicationContext().getResources(), resource);
circularBitmapDrawable.setCornerRadius(dpToPx(10));
circularBitmapDrawable.setAntiAlias(true);
imageView.setImageDrawable(circularBitmapDrawable);
}
});
public int dpToPx(int dp) {
DisplayMetrics displayMetrics = getApplicationContext().getResources().getDisplayMetrics();
return Math.round(dp * (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
}
Avec l'aide de glide library et RoundedBitmapDrawableFactory class, c'est facile à réaliser. Vous devrez peut-être créer une image d'espace réservé circulaire.
Glide.with(context)
.load(imgUrl)
.asBitmap()
.placeholder(R.drawable.placeholder)
.error(R.drawable.placeholder)
.into(new BitmapImageViewTarget(imgProfilePicture) {
@Override
protected void setResource(Bitmap resource) {
RoundedBitmapDrawable drawable = RoundedBitmapDrawableFactory.create(context.getResources(),
Bitmap.createScaledBitmap(resource, 50, 50, false));
drawable.setCornerRadius(10); //drawable.setCircular(true);
imgProfilePicture.setImageDrawable(drawable);
}
});
Répondez à la question qui est redirigée ici: "Comment créer un ImageView circulaire dans Android?"
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;
}
Kotlin
import Android.graphics.BitmapFactory
import Android.os.Bundle
import Android.support.v4.graphics.drawable.RoundedBitmapDrawableFactory
import kotlinx.Android.synthetic.main.activity_main.*
val bitmap = BitmapFactory.decodeResource(resources, R.drawable.myImage)
val rounded = RoundedBitmapDrawableFactory.create(resources, bitmap)
rounded.cornerRadius = 20f
profileImageView.setImageDrawable(rounded)
Pour rendre la circulaire ImageView
, nous pouvons modifier cornerRadius
par:
rounded.isCircular = true
Pour ceux qui utilisent Glide et Kotlin, vous pouvez y parvenir en étendant RequestBuilder
fun <T> GlideRequest<T>.roundCorners(cornerRadius: Int) =
apply(RequestOptions().transform(RoundedCorners(cornerRadius)))
et utiliser comme;
GlideApp.with(context)
.load(url)
.roundCorners(context.resources.getDimension(R.dimen.radius_in_dp).toInt())
.into(imgView)
Vous pouvez essayer cette bibliothèque - RoundedImageView
Il est:
ImageView rapide qui prend en charge les angles arrondis, les ovales et les cercles. Un sur-ensemble complet de CircleImageView.
Je l'ai utilisé dans mon projet et c'est très facile.
Utilisez cette option pour obtenir une image circulaire avec une bordure.
public static Bitmap getCircularBitmapWithBorder(Bitmap bitmap, int bordercolor) {
if (bitmap == null || bitmap.isRecycled()) {
return null;
}
int borderWidth=(int)(bitmap.getWidth()/40);
final int width = bitmap.getWidth() + borderWidth;
final int height = bitmap.getHeight() + borderWidth;
Bitmap canvasBitmap = Bitmap.createBitmap(width, height,
Bitmap.Config.ARGB_8888);
BitmapShader shader = new BitmapShader(bitmap, TileMode.CLAMP,
TileMode.CLAMP);
Paint paint = new Paint();
Paint.setAntiAlias(true);
Paint.setShader(shader);
Canvas canvas = new Canvas(canvasBitmap);
float radius = width > height ? ((float) height) / 2f
: ((float) width) / 2f;
canvas.drawCircle(width / 2, height / 2, radius, Paint);
Paint.setShader(null);
Paint.setStyle(Paint.Style.STROKE);
Paint.setColor(bordercolor);
Paint.setStrokeWidth(borderWidth);
canvas.drawCircle(width / 2, height / 2, radius - borderWidth / 2,
Paint);
return canvasBitmap;
}
Beaucoup de réponses!
J'ai suivi cet exemple que quelques personnes ont également suggéré: http://www.techrepublic.com/article/pro-tip-round-corners-on-an-Android-imageview-with-this-hack/
Cependant, il me fallait un cercle coloré derrière une image transparente. Pour ceux qui sont intéressés à faire de même ...
1) Réglez FrameLayout sur la largeur et la hauteur - dans mon cas, la taille de l'image (50dp).
2) Placez le ImageView portant le src = "@drawable/..." au-dessus du ImageView contenant l’image. Donnez-lui un identifiant, dans mon cas je l'ai appelé iconShape
3) Drawable mask.xml doit avoir une couleur unie de #ffffffff 4. Si vous souhaitez modifier dynamiquement la couleur du cercle dans votre code, faites
ImageView iv2 = (ImageView) v.findViewById(R.id.iconShape);
Drawable shape = getResources().getDrawable(R.drawable.mask);
shape.setColorFilter(Color.BLUE, Mode.MULTIPLY);
iv2.setImageDrawable(shape);
J'utilise une vue personnalisée que je mets au-dessus des autres et que dessine simplement les 4 petits coins inversés de la même couleur que l'arrière-plan.
Avantages:
Code:
public class RoundedCornersView extends View {
private float mRadius;
private int mColor = Color.WHITE;
private Paint mPaint;
private Path mPath;
public RoundedCornersView(Context context) {
super(context);
init();
}
public RoundedCornersView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
TypedArray a = context.getTheme().obtainStyledAttributes(
attrs,
R.styleable.RoundedCornersView,
0, 0);
try {
setRadius(a.getDimension(R.styleable.RoundedCornersView_radius, 0));
setColor(a.getColor(R.styleable.RoundedCornersView_cornersColor, Color.WHITE));
} finally {
a.recycle();
}
}
private void init() {
setColor(mColor);
setRadius(mRadius);
}
private void setColor(int color) {
mColor = color;
mPaint = new Paint();
mPaint.setColor(mColor);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setAntiAlias(true);
invalidate();
}
private void setRadius(float radius) {
mRadius = radius;
RectF r = new RectF(0, 0, 2 * mRadius, 2 * mRadius);
mPath = new Path();
mPath.moveTo(0,0);
mPath.lineTo(0, mRadius);
mPath.arcTo(r, 180, 90);
mPath.lineTo(0,0);
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
/*This just draws 4 little inverted corners */
int w = getWidth();
int h = getHeight();
canvas.drawPath(mPath, mPaint);
canvas.save();
canvas.translate(w, 0);
canvas.rotate(90);
canvas.drawPath(mPath, mPaint);
canvas.restore();
canvas.save();
canvas.translate(w, h);
canvas.rotate(180);
canvas.drawPath(mPath, mPaint);
canvas.restore();
canvas.translate(0, h);
canvas.rotate(270);
canvas.drawPath(mPath, mPaint);
}
}
vous pouvez utiliser roundedImageView Library très facilement:
compile 'com.makeramen:roundedimageview:2.3.0'
et alors:
<com.makeramen.roundedimageview.RoundedImageView
xmlns:app="http://schemas.Android.com/apk/res-auto"
Android:id="@+id/img_episode"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:elevation="7dp"
app:riv_border_color="@color/colorPrimary"
app:riv_border_width="1dip"
app:riv_corner_radius="10dip"
app:riv_mutate_background="true"
/>
voici ma solution:
<com.myproject.ui.RadiusCornerImageView
Android:id="@+id/imageViewPhoto"
Android:layout_width="160dp"
Android:layout_height="160dp"
app:corner_radius_dp="5"
app:corner_radius_position="top"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
Et en code Java:
public class RadiusCornerImageView extends Android.support.v7.widget.AppCompatImageView {
private int cornerRadiusDP = 0; // dp
private int corner_radius_position;
public RadiusCornerImageView(Context context) {
super(context);
}
public RadiusCornerImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public RadiusCornerImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
TypedArray typeArray = context.getTheme().obtainStyledAttributes(attrs, R.styleable.RadiusCornerImageView, 0, 0);
try {
cornerRadiusDP = typeArray.getInt(R.styleable.RadiusCornerImageView_corner_radius_dp, 0);
corner_radius_position = typeArray.getInteger(R.styleable.RadiusCornerImageView_corner_radius_position, 0);
} finally {
typeArray.recycle();
}
}
@Override
protected void onDraw(Canvas canvas) {
float radiusPx = AndroidUtil.dpToPx(getContext(), cornerRadiusDP);
Path clipPath = new Path();
RectF rect = null;
if (corner_radius_position == 0) { // all
// round corners on all 4 angles
rect = new RectF(0, 0, this.getWidth(), this.getHeight());
} else if (corner_radius_position == 1) {
// round corners only on top left and top right
rect = new RectF(0, 0, this.getWidth(), this.getHeight() + radiusPx);
} else {
throw new IllegalArgumentException("Unknown corner_radius_position = " + corner_radius_position);
}
clipPath.addRoundRect(rect, radiusPx, radiusPx, Path.Direction.CW);
canvas.clipPath(clipPath);
super.onDraw(canvas);
}
}
/**
* Background Async task to load user profile picture from url
*/
private class LoadProfileImage extends AsyncTask<String, Void, RoundedBitmapDrawable> {
ImageView profileImageView;
public LoadProfileImage(ImageView profileImageView) {
this.profileImageView = profileImageView;
}
protected RoundedBitmapDrawable doInBackground(String... urls) {
String photoUrl = urls[0];
RoundedBitmapDrawable profileRoundedDrawable = null;
try {
InputStream inputStream = new Java.net.URL(photoUrl).openStream();
Resources res = getResources();
profileRoundedDrawable = RoundedBitmapDrawableFactory.create(res, inputStream);
profileRoundedDrawable.setCircular(true);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return profileRoundedDrawable;
}
protected void onPostExecute(RoundedBitmapDrawable result) {
profileImageView.setImageDrawable(result);
}
}
J'ai utilisé un chemin pour dessiner uniquement des coins sur le canevas d'image (j'avais besoin d'une solution sans allocation de mémoire bitmap).
@Override
protected void onDraw(final Canvas canvas) {
super.onDraw(canvas);
if (!hasRoundedCorners()) return;
mPaint.setStyle(Paint.Style.FILL);
mPaint.setStrokeWidth(0);
Path path = new Path();
path.setFillType(Path.FillType.INVERSE_WINDING);
path.addRoundRect(new RectF(0, 0, getWidth(), getHeight()), mRadius, mRadius, Path.Direction.CCW);
canvas.drawPath(path, mPaint);
}
remarquez que vous ne devez pas allouer de nouvel objet à la méthode onDraw. Ce code est une preuve de concept et ne doit pas être utilisé de la sorte dans le code produit
voir plus: https://medium.com/@przemek.materna/rounded-image-view-no-bitmap-reallocation-11a8b163484d
**In Layout**
Make your ImageView like
<com.example..CircularImageView
Android:id="@+id/profile_image_round_corner"
Android:layout_width="80dp"
Android:layout_height="80dp"
Android:scaleType="fitCenter"
Android:padding="2dp"
Android:background="@null"
Android:adjustViewBounds="true"
Android:layout_centerInParent="true"
Android:src="@drawable/dummy" />
**And Create a Class**
package com.example;
import Java.util.Formatter.BigDecimalLayoutForm;
import Android.content.Context;
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.Rect;
import Android.graphics.drawable.BitmapDrawable;
import Android.graphics.drawable.Drawable;
import Android.util.AttributeSet;
import Android.widget.ImageView;
public class CircularImageView extends ImageView {
public CircularImageView(Context context) {
super(context);
}
public CircularImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CircularImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onDraw(Canvas canvas) {
Drawable drawable = getDrawable();
if (drawable == null) {
return;
}
if (getWidth() == 0 || getHeight() == 0) {
return;
}
Bitmap b = ((BitmapDrawable) drawable).getBitmap();
Bitmap bitmap = b.copy(Bitmap.Config.ARGB_8888, true);
int w = getWidth(), h = getHeight();
Bitmap roundBitmap = getRoundBitmap(bitmap, w);
canvas.drawBitmap(roundBitmap, 0, 0, null);
}
public static Bitmap getRoundBitmap(Bitmap bmp, int radius) {
Bitmap sBmp;
if (bmp.getWidth() != radius || bmp.getHeight() != radius) {
float smallest = Math.min(bmp.getWidth(), bmp.getHeight());
float factor = smallest / radius;
sBmp = Bitmap.createScaledBitmap(bmp, (int)(bmp.getWidth() / factor), (int)(bmp.getHeight() / factor), false);
} else {
sbmp = bmp;
}
Bitmap output = Bitmap.createBitmap(radius, radius,
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xffa19774;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, radius, radius);
Paint.setAntiAlias(true);
Paint.setFilterBitmap(true);
Paint.setDither(true);
canvas.drawARGB(0, 0, 0, 0);
Paint.setColor(Color.parseColor("#BAB399"));
canvas.drawCircle(radius / 2 + 0.7f,
radius / 2 + 0.7f, radius / 2 + 0.1f, Paint);
Paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(sBmp, rect, rect, Paint);
return output;
}
}
Pour Glide 4.x.x
utiliser ce code simple
Glide
.with(context)
.load(uri)
.apply(
RequestOptions()
.circleCrop())
.into(imageView)
Ce n'est pas exactement la solution, mais c'est une solution similaire. Cela peut aider les gens qui étaient dans le même bateau que moi.
Mon image, un logo d'application, avait un arrière-plan transparent et j'appliquais un dégradé XML comme arrière-plan. J'ai ajouté les marges de remplissage nécessaires à l'imageView en XML, puis je l'ai ajouté comme fond d'écran:
<?xml version="1.0" encoding="utf-8"?>
<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>
Si l’un de vous est fait face à ce problème
Très probablement, vous utilisez Android Studio . En raison de la taille de l'image, et de tous dans Android Studio, vous pouvez rencontrer ce problème Une solution facile à ce problème consiste à diminuer le rayon du cercle dans drawCircle()
. Dans mon cas, j'utilise ce correctif
Utiliser canvas.drawCircle(100, 100, 90, Paint);
au lieu de canvas.drawCircle(100, 100, 100, Paint);
résoudra définitivement votre problème.
Voici le code finalement édité: -
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);
}
}
Bien que les deux premières réponses fonctionnent, je souhaite en décrire un peu plus… .. Disons que vous avez une activité ou un fragment où se trouve votre ImageView. Vous souhaitez dessiner une image et la redimensionner proportionnellement. Ensuite, vous devriez écrire dans onCreate ou onCreateView comme suit:
LinearLayout rootLayout = (LinearLayout) findViewById(R.id.rootLayout);
ImageView image = (ImageView) findViewById(R.id.image);
// Wait till an activity is visible and image can be measured.
rootLayout.post(new Runnable() {
@Override
public void run() {
// Setting ImageView height with aspect ratio.
Drawable drawable = ContextCompat.getDrawable(getActivity(), R.drawable.your_image);
int height = getImageViewHeight(drawable, image);
// Rounding image corners.
float radius = getResources().getDimension(R.dimen.your_radius_in_dp);
Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
Bitmap result = getRoundedBitmap(bitmap, image.getWidth(), height, radius);
image.setImageBitmap(result);
}
});
Où définir une nouvelle hauteur d'image est:
public static int getImageViewHeight(Drawable drawable, ImageView imageView) {
imageView.setImageDrawable(drawable);
int width = drawable.getIntrinsicWidth();
int height = 0;
if (width > 0) {
height = (drawable.getIntrinsicHeight() * imageView.getWidth()) / width;
imageView.getLayoutParams().height = height;
imageView.requestLayout();
}
return height;
}
Ensuite, vous devriez écrire une méthode pour redimensionner une image et arrondir ses angles. Ici, largeur et hauteur sont les nouvelles dimensions d'un bitmap (plus petit ou plus grand). Dans l'exemple suivant, j'arrondis seulement deux coins supérieurs .
private Bitmap getRoundedBitmap(Bitmap bitmap, int width, int height, float radius) {
// Create scaled bitmap.
Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap, width, height, false);
BitmapShader shader = new BitmapShader(scaledBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
Paint paint = new Paint();
Paint.setAntiAlias(true);
Paint.setShader(shader);
Bitmap result = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(result);
// First make all corners round.
canvas.drawRoundRect(new RectF(0, 0, width, height), radius, radius, Paint);
// Then draw bottom rectangle.
canvas.drawRect(0, height - radius, radius, height, Paint);
canvas.drawRect(width - radius, height - radius, width, height, Paint);
return result;
}
Grâce à melanke , vous pouvez utiliser une classe personnalisée et créer une circulaire ImageView
personnalisée.
import Android.content.Context;
import Android.graphics.Bitmap;
import Android.graphics.Bitmap.Config;
import Android.graphics.Canvas;
import Android.graphics.Color;
import Android.graphics.Paint;
import Android.graphics.PorterDuff.Mode;
import Android.graphics.PorterDuffXfermode;
import Android.graphics.Rect;
import Android.graphics.drawable.BitmapDrawable;
import Android.graphics.drawable.Drawable;
import Android.util.AttributeSet;
public class MLRoundedImageView extends Android.support.v7.widget.AppCompatImageView {
public MLRoundedImageView(Context context) {
super(context);
}
public MLRoundedImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MLRoundedImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onDraw(Canvas canvas) {
Drawable drawable = getDrawable();
if (drawable == null) {
return;
}
if (getWidth() == 0 || getHeight() == 0) {
return;
}
Bitmap b = ((BitmapDrawable) drawable).getBitmap();
Bitmap bitmap = b.copy(Bitmap.Config.ARGB_8888, true);
int w = getWidth(), h = getHeight();
Bitmap roundBitmap = getCroppedBitmap(bitmap, w);
canvas.drawBitmap(roundBitmap, 0, 0, null);
}
public static Bitmap getCroppedBitmap(Bitmap bmp, int radius) {
Bitmap sbmp;
if (bmp.getWidth() != radius || bmp.getHeight() != radius) {
float smallest = Math.min(bmp.getWidth(), bmp.getHeight());
float factor = smallest / radius;
sbmp = Bitmap.createScaledBitmap(bmp, (int)(bmp.getWidth() / factor), (int)(bmp.getHeight() / factor), false);
} else {
sbmp = bmp;
}
Bitmap output = Bitmap.createBitmap(radius, radius,
Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xffa19774;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, radius, radius);
Paint.setAntiAlias(true);
Paint.setFilterBitmap(true);
Paint.setDither(true);
canvas.drawARGB(0, 0, 0, 0);
Paint.setColor(Color.parseColor("#BAB399"));
canvas.drawCircle(radius / 2 + 0.7f,
radius / 2 + 0.7f, radius / 2 + 0.1f, Paint);
Paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(sbmp, rect, rect, Paint);
return output;
}
}
Et utilisez-le ensuite en XML comme:
<your.package.name.MLRoundedImageView
..
/>
Essaye ça
Bitmap finalBitmap;
if (bitmap.getWidth() != radius || bitmap.getHeight() != radius)
finalBitmap = Bitmap.createScaledBitmap(bitmap, radius, radius,
false);
else
finalBitmap = bitmap;
Bitmap output = Bitmap.createBitmap(finalBitmap.getWidth(),
finalBitmap.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, finalBitmap.getWidth(),
finalBitmap.getHeight());
Paint.setAntiAlias(true);
Paint.setFilterBitmap(true);
Paint.setDither(true);
canvas.drawARGB(0, 0, 0, 0);
Paint.setColor(Color.parseColor("#BAB399"));
canvas.drawCircle(finalBitmap.getWidth() / 2 + 0.7f,
finalBitmap.getHeight() / 2 + 0.7f,
finalBitmap.getWidth() / 2 + 0.1f, Paint);
Paint.setXfermode(new PorterDuffXfermode(
Android.graphics.PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(finalBitmap, rect, rect, Paint);
return output;
En utilisant le code ci-dessous, vous pouvez modifier le rayon du coin supérieur
val image = findViewById<ImageView>(R.id.image)
val curveRadius = 20F
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Lollipop) {
image.outlineProvider = object : ViewOutlineProvider() {
@RequiresApi(Build.VERSION_CODES.Lollipop)
override fun getOutline(view: View?, outline: Outline?) {
outline?.setRoundRect(0, 0, view!!.width, (view.height+curveRadius).toInt(), curveRadius)
}
}
image.clipToOutline = true
}