I am looking at using the Picasso library to download an image from URL and pass this into circle image view, but since picasso requires that you pass in an actual imageView I have come to a standstill on how to do it
I am using the picasso library from here http://square.github.io/picasso/
and the circle image view class from here https://github.com/hdodenhof/CircleImageView
Here is the start of my code to get the image
private void getData() {
userName.setText(prefs.getString("userName",""));
jobTitle.setText(prefs.getString("profile",""));
userLocation.setText(prefs.getString("location",""));
// ??????
// Picasso.with(context).load(image link here).into(imageview here);
//CircleImageView img = new CircleImageView(this);
//img.setImageResource();
//img.setImageBitmap();
//img.setImageDrawable();
//img.setImageURI();
}
Edit:
here is the xml for the circleImageView
<michael.CircleImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:src="#drawable/shadow"
android:layout_gravity="center"
android:layout_marginTop="16dp"
app:border_width="2dp"
app:border_color="#274978"
android:id="#+id/circleImageView"
I don't think you require CircleImageView library
You can implement Circular Transformation check the below gist
https://gist.github.com/julianshen/5829333
then
Picasso.with(activity).load(image link here)
.transform(new CircleTransform()).into(ImageView);
Use This
Activity Class
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String imageUrl = "https://www.baby-connect.com/images/baby2.gif";
CircleImageView imageView = (CircleImageView) findViewById(R.id.image);
Picasso.with(getApplicationContext()).load(imageUrl)
.placeholder(R.drawable.images).error(R.drawable.ic_launcher)
.into(imageView);
}
}
Layout File
<de.hdodenhof.circleimageview.CircleImageView
android:id="#+id/image"
android:layout_width="160dp"
android:layout_height="160dp"
android:layout_centerInParent="true"
android:src="#drawable/images"
app:border_color="#ffffff"
app:border_width="2dp" />
This is Working fine.
Use this code to create Circular Imageview ....
public class RoundedImageView extends ImageView {
public RoundedImageView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public RoundedImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public RoundedImageView(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)
sbmp = Bitmap.createScaledBitmap(bmp, radius, radius, false);
else
sbmp = bmp;
Bitmap output = Bitmap.createBitmap(sbmp.getWidth(),
sbmp.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xffa19774;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, sbmp.getWidth(), sbmp.getHeight());
paint.setAntiAlias(true);
paint.setFilterBitmap(true);
paint.setDither(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(Color.parseColor("#BAB399"));
canvas.drawCircle(sbmp.getWidth() / 2+0.7f, sbmp.getHeight() / 2+0.7f,
sbmp.getWidth() / 2+0.1f, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(sbmp, rect, rect, paint);
return output;
}
}
Take the ID of CircleImageView first :
CircleImageView mCircleImageView = (CircleImageView)findViewById(R.id.circleImageView);
And pass the ID to Picasso library :
Picasso.with(mContext).load(Uri.parse(link)).placeholder(drawable).into(mCircleImageView);
This worked for me.
I have created a target class that uses native Android's RoundedBitmapDrawable class to make image round (removes the need to add a circle transform class to code), see solution below:
public class RoundedImageBitmapTarget implements Target {
private final Context context;
private final ImageView view;
public RoundedImageBitmapTarget(Context context, ImageView view) {
this.context = context;
this.view = view;
}
#Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
setBitmap(bitmap);
}
#Override
public void onBitmapFailed(Drawable errorDrawable) {
setBitmap(((BitmapDrawable) errorDrawable).getBitmap());
}
#Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
setBitmap(((BitmapDrawable) placeHolderDrawable).getBitmap());
}
public void setBitmap(Bitmap bitmap) {
view.setImageDrawable(getRoundBitmap(context, bitmap));
}
public static RoundedBitmapDrawable getRoundBitmap(Context context, Bitmap bitmap) {
Resources res = context.getResources();
RoundedBitmapDrawable round = RoundedBitmapDrawableFactory.create(res, bitmap);
round.setCircular(true);
round.setTargetDensity(context.getResources().getDisplayMetrics());
return round;
}
public static void load(Context context, ImageView view, String url, int size, #DrawableRes int placeholder) {
RoundedImageBitmapTarget target;
Picasso.with(context).load(url)
.resize(0, size)
.placeholder(placeholder)
.error(placeholder)
.into(target = new RoundedImageBitmapTarget(context, view));
view.setTag(target);
}
}
Related
I'm using a custom class (extension of ImageView) to have an XML round image view. The problem is when I call .setColorFilter() it doesn't adhere to the same circular/round bounds.
How can I make the color filter only affect the image and not the entire rectangle of the view?
Here is my custom class for reference:
public class RoundedCornerImageFilterView extends ImageFilterView {
public RoundedCornerImageFilterView(Context context) {
super(context);
}
public RoundedCornerImageFilterView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public RoundedCornerImageFilterView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public void setImageFilter(int color) {
this.setColorFilter(color, PorterDuff.Mode.SRC_IN);
}
#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();
int h = getHeight();
Bitmap roundedCornerBitmap = getRoundedCornerBitmap(bitmap, h, w);
canvas.drawBitmap(roundedCornerBitmap, 0, 0, null);
}
public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, int height, int width) {
Bitmap sbmp;
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xff424242;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0,
(width), (height));
final RectF rectF = new RectF(rect);
final float roundPx = 28;
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return output;
}
}
My xml implementation:
<MY_PATH.RoundedCornerImageFilterView
android:id="#+id/MY_IMAGE_VIEW"
android:layout_width="match_parent"
android:layout_height="150dp"
/>
Me trying to set the color filter:
MY_IMAGE_VIEW.setColorFilter(Color.parseColor(color), PorterDuff.Mode.OVERLAY)
Before the filter (looking like it's supposed to):
After setting the filter (you can see the square edges now):
Although the image (bitmap) has been given rounded corners, the canvas that it is written to has not. Since the color filter is being applied to the canvas, the tint spills out into the corners.
I suggest that you apply a rounded rectangle to a path then clip the path to the canvas. Something like this:
public class RoundedImageView extends AppCompatImageView {
private final Path mPath = new Path();
public RoundedImageView(Context context) {
super(context);
init();
}
public RoundedImageView(Context context, #Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
public RoundedImageView(Context context, #Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
setColorFilter(Color.RED, PorterDuff.Mode.OVERLAY);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mPath.reset();
mPath.addRoundRect(new RectF(0, 0, w, h), 128, 128, Path.Direction.CW);
}
#Override
public void draw(Canvas canvas) {
canvas.save();
canvas.clipPath(mPath);
super.draw(canvas);
canvas.restore();
}
}
I am using ImageView here, but the concept remains the same.
If you do this type of clipping, then rounding the bitmap becomes superfluous since it will also be clipped to the path.
I'm using a https://github.com/hdodenhof/CircleImageView library, but also tried several others and it didn't help. I need to load image from server with picasso, like this mPicasso.load(url).into(mCircularImageView). However I always get this:
But I need to achieve this:
Tried to call resize(100,100), fit(), transform(new CircleTransorm()),
public class CircleTransform implements Transformation {
#Override
public Bitmap transform(Bitmap source) {
int size = Math.min(source.getWidth(), source.getHeight());
int x = (source.getWidth() - size) / 2;
int y = (source.getHeight() - size) / 2;
Bitmap squaredBitmap = Bitmap.createBitmap(source, x, y, size, size);
if (squaredBitmap != source) {
source.recycle();
}
Bitmap bitmap = Bitmap.createBitmap(size, size, source.getConfig());
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint();
BitmapShader shader = new BitmapShader(squaredBitmap,
BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP);
paint.setShader(shader);
paint.setAntiAlias(true);
float r = size / 2f;
canvas.drawCircle(r, r, r, paint);
squaredBitmap.recycle();
return bitmap;
}
#Override
public String key() {
return "circle";
}
}
nothing of the above helped.
My layout:
<de.hdodenhof.circleimageview.CircleImageView
android:id="#+id/account_profile_picture"
style="#style/ProfilePicture"
android:layout_gravity="center_horizontal"/>
Style:
<style name="ProfilePicture">
<item name="android:layout_width">#dimen/profile_picture_size</item>
<item name="android:layout_height">#dimen/profile_picture_size</item>
<item name="android:src">#drawable/profile_picture_placeholder</item>
<item name="civ_border_width">1dp</item>
<item name="civ_border_color">#FF000000</item>
</style>
White fit() defers the call until the view is loaded and measured, it does not achieve the results that you want. You need to add centerCrop() in order to achieve the expected output:
mPicasso.load(url).fit().centerCrop().into(mCircularImageView)
Just set this attribute to your circleimageview
android:scaleType="centerCrop"
This should do it.
Thank You
please use this you can create dynamic imageview, i hope this will help you.
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 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, 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(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(sbmp, rect, rect, paint);
return output;
}
}
You dont need to add any library for circular image view.
Android api already provides
RoundedBitmapDrawable
to use for this purpose. I have used Glide library to do what you want -
Glide.with(context)
.load(imageUrl)
.asBitmap()
.placeholder(R.color.gray)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.centerCrop()
.into(new BitmapImageViewTarget(imageView){
#Override
public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
RoundedBitmapDrawable circularBitmapDrawable =
RoundedBitmapDrawableFactory.create(context.getResources(), resource);
circularBitmapDrawable.setCircular(true);
imageView.setImageDrawable(circularBitmapDrawable);
}
#Override
public void onLoadFailed(Exception e, Drawable errorDrawable) {
imageView.setImageResource(R.drawable.profile);
}
});
What I am seeing in your code is you are using both circle transformation and circle image view. for make circle you have to use only one approach, I am suggestion go with circle transformation also change your circle image view to simple image view.
mPicasso.load(url).resize(300,300).centerCrop().transform (new CircleTransform ()).into(mImageView);
hope It will help.
I am trying to get rounded border for an imageview. Here is the code for it:
http://stackoverflow.com/a/3292810/4224275
My problem is for a normal imageview declared as follows, how do I use the class object to make the image rounded. Here is my code which didn't work.
private ImageView imageView;
imageView = (ImageView) findViewById(R.id.imageView1);
imageView.buildDrawingCache();
Bitmap bmap = imageView.getDrawingCache();
ImageHelper imh = new ImageHelper();
imh.getRoundedCornerBitmap(bmap, 10);
It doesn't work for me. I don't know what to do.
Here is the logcat output:
Take a look in my example:
public class RoundedNetworkImageView extends NetworkImageView {
public RoundedNetworkImageView(Context context) {
super(context);
}
public RoundedNetworkImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public RoundedNetworkImageView(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 _bitmap = ((BitmapDrawable)_drawable)
.getBitmap().copy(Bitmap.Config.ARGB_8888, true);
canvas.drawBitmap(getCroppedBitmap(_bitmap, (int) (getWidth() / 1.2f)), 0,0, null);
}
public static Bitmap getCroppedBitmap(Bitmap bitmap, int radius) {
Bitmap _newBitmap;
if(bitmap.getWidth() != radius || bitmap.getHeight() != radius) {
_newBitmap = Bitmap.createScaledBitmap(bitmap, radius, radius, false);
}
else{
_newBitmap = bitmap;
}
Bitmap _outBitmap = Bitmap.createBitmap(_newBitmap.getWidth(),
_newBitmap.getHeight(), Bitmap.Config.ARGB_8888);
Canvas _canvas = new Canvas(_outBitmap);
Paint _paint = new Paint();
Rect _rect = new Rect(0, 0, _newBitmap.getWidth(), _newBitmap.getHeight());
_paint.setAntiAlias(true);
_paint.setFilterBitmap(true);
_paint.setDither(true);
_canvas.drawARGB(0, 0, 0, 0);
_paint.setColor(Color.parseColor("#BAB399"));
_canvas.drawCircle(_newBitmap.getWidth() / 2, _newBitmap.getHeight() / 2,
_newBitmap.getWidth() / 2.5f, _paint);
_paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
_canvas.drawBitmap(_newBitmap, _rect, _rect, _paint);
return _outBitmap;
}
}
In the xml:
<com.android.volley.toolbox.NetworkImageView
android:id="#+id/imgShot_shotDetail"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"/>
In the activity:
NetworkImageView imgShot = headerView.findViewById(R.id.imgShot_shotDetail);
imgShot.setImageUrl(url, AppControllerImage.getInstance().getImageLoader());
imgShot.setDefaultImageResId(R.drawable.notfound);
imgShot.setErrorImageResId(R.drawable.notfound);
In this case, I've used NetworkImageView from Volley library, but you can use a ImageView instead. You just have to adapt the code.
I am working on an Android application in which I am doing rounded image view. It is working fine with some images, but for the images like 160x120 resolution it shows an oval shaped.
My code for the custom imageview is given below:
public class RoundImage extends Drawable {
private final Bitmap mBitmap;
private final Paint mPaint;
private final RectF mRectF;
private final int mBitmapWidth;
private final int mBitmapHeight;
public RoundImage(Bitmap bitmap) {
mBitmap = bitmap;
mRectF = new RectF();
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
final BitmapShader shader = new BitmapShader(bitmap,
Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
mPaint.setShader(shader);
mBitmapWidth = mBitmap.getWidth();
mBitmapHeight = mBitmap.getHeight();
}
#Override
public void draw(Canvas canvas) {
canvas.drawOval(mRectF, mPaint);
}
#Override
protected void onBoundsChange(Rect bounds) {
super.onBoundsChange(bounds);
mRectF.set(bounds);
}
#Override
public void setAlpha(int alpha) {
if (mPaint.getAlpha() != alpha) {
mPaint.setAlpha(alpha);
invalidateSelf();
}
}
#Override
public void setColorFilter(ColorFilter cf) {
mPaint.setColorFilter(cf);
}
#Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
#Override
public int getIntrinsicWidth() {
return mBitmapWidth;
}
#Override
public int getIntrinsicHeight() {
return mBitmapHeight;
}
public void setAntiAlias(boolean aa) {
mPaint.setAntiAlias(aa);
invalidateSelf();
}
#Override
public void setFilterBitmap(boolean filter) {
mPaint.setFilterBitmap(filter);
invalidateSelf();
}
#Override
public void setDither(boolean dither) {
mPaint.setDither(dither);
invalidateSelf();
}
public Bitmap getBitmap() {
return mBitmap;
}
}
// My main Activity Class
public class MainActivity extends Activity {
ImageView imageView1, imageView2;
RoundImage roundedImage, roundedImage1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView1 = (ImageView) findViewById(R.id.imageView1);
Bitmap bm = BitmapFactory.decodeResource(getResources(),R.drawable.tt);
roundedImage = new RoundImage(bm);
imageView1.setImageDrawable(roundedImage);
}
}
// My xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/White"
android:orientation="vertical" >
<ImageView
android:id="#+id/imageView1"
android:layout_width="100dp"
android:layout_height="100dp"
android:scaleType="centerCrop"
android:layout_gravity="center"
android:background="#color/Brown"
android:src="#drawable/image" />
</LinearLayout>
Add this gradle in your android project
compile 'com.mikhaellopez:circularimageview:3.0.2'
and added this line in your xml file (layout files)
<com.mikhaellopez.circularimageview.CircularImageView
android:layout_width="250dp"
android:layout_height="250dp"
android:src="#drawable/image"
app:civ_border_color="#EEEEEE"
app:civ_border_width="4dp"
app:civ_shadow="true"
app:civ_shadow_radius="10"
app:civ_shadow_color="#8BC34A"/>
In your java code
CircularImageView circularImageView = (CircularImageView)findViewById(R.id.yourCircularImageView);
// Set Border
circularImageView.setBorderColor(getResources().getColor(R.color.GrayLight));
circularImageView.setBorderWidth(10);
// Add Shadow with default param
circularImageView.addShadow();
// or with custom param
circularImageView.setShadowRadius(15);
circularImageView.setShadowColor(Color.RED);
From here
First of all use Picasso image loading library, for that you have to add one dependency like in build.gradle:
compile 'com.squareup.picasso:picasso:2.5.2'
than create a seperate class called "CircleTransform" for displaying image into round shape and implements interface "Transformation"
than add following conde into it.
#Override
public Bitmap transform(Bitmap source) {
int size = Math.min(source.getWidth(), source.getHeight());
int x = (source.getWidth() - size) / 2;
int y = (source.getHeight() - size) / 2;
Bitmap squaredBitmap = Bitmap.createBitmap(source, x, y, size, size);
if (squaredBitmap != source) {
source.recycle();
}
Bitmap bitmap = Bitmap.createBitmap(size, size, source.getConfig());
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint();
BitmapShader shader = new BitmapShader(squaredBitmap, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP);
paint.setShader(shader);
paint.setAntiAlias(true);
float r = size/2f;
canvas.drawCircle(r, r, r, paint);
squaredBitmap.recycle();
return bitmap;
}
#Override
public String key() {
return "circle";
}
After that you can set image into imageview like this :
Picasso.with(this)
.load(R.drawable.tt)
.transform(new CircleTransform())
.into(imageView1);
That's it. i hope it helps.
Requirement is to:
Req 1 : Fetch images from url
R2: save them in cache
R3: make ImageView rounded not the image
So for R1 & R2 I found a library:
http://loopj.com/android-smart-image-view/
For R3 I've done a lot of R&D , & everything I found converts the image not the ImageView. This is what I've searched:
Mask ImageView with round corner background
How to make an ImageView with rounded corners?
https://github.com/vinc3m1/RoundedImageView
https://github.com/lopspower/CircularImageView
I know it's possible to use the ImageView bitmap & get the image rounded but with the specific library I want to use that isn't possible(maybe possible with very complex threading).
So please help me to get the ImageView rounded not the image.
so this is the minimalistic version:
class RoundImageView extends ImageView {
private static final int RADIUS = 32;
private Paint mPaint;
private Paint mSrcIn;
private RectF mRect;
public RoundImageView(Context context) {
super(context);
// setBackgroundColor(0xffffffff);
mSrcIn = new Paint();
mSrcIn.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mRect = new RectF();
}
#Override
public void onDraw(Canvas canvas) {
Drawable dr = getDrawable();
if (dr != null) {
mRect.set(dr.getBounds());
getImageMatrix().mapRect(mRect);
mRect.offset(getPaddingLeft(), getPaddingTop());
int rtc = canvas.saveLayer(mRect, null, Canvas.ALL_SAVE_FLAG);
// draw DST
canvas.drawRoundRect(mRect, RADIUS, RADIUS, mPaint);
canvas.saveLayer(mRect, mSrcIn, Canvas.ALL_SAVE_FLAG);
// draw SRC
super.onDraw(canvas);
canvas.restoreToCount(rtc);
}
}
}
or use even shorter one when hardware acceleration is not used and you can use Canvas.clipPath:
class RoundImageViewClipped extends ImageView {
private static final int RADIUS = 32;
private RectF mRect;
private Path mClip;
public RoundImageViewClipped(Context context) {
super(context);
// setBackgroundColor(0xffffffff);
mRect = new RectF();
mClip = new Path();
}
#Override
public void onDraw(Canvas canvas) {
Drawable dr = getDrawable();
if (dr != null) {
mRect.set(dr.getBounds());
getImageMatrix().mapRect(mRect);
mRect.offset(getPaddingLeft(), getPaddingTop());
mClip.reset();
mClip.addRoundRect(mRect, RADIUS, RADIUS, Direction.CCW);
canvas.clipPath(mClip);
super.onDraw(canvas);
}
}
}
I'm pretty sure you can't "make the ImageView round," since all Views are actually rectangular, so what you're going to have to do is fake it.
Use a method like this to cut a circle from the image:
public Bitmap getRoundedBitmap(Bitmap scaleBitmapImage) {
int targetRadius = scaleBitmapImage.getWidth();
if(targetRadius > scaleBitmapImage.getHeight()) targetRadius = scaleBitmapImage.getHeight();
Bitmap targetBitmap = Bitmap.createBitmap(targetRadius, targetRadius, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(targetBitmap);
Path path = new Path();
path.addCircle(((float) scaleBitmapImage.getWidth() - 1) / 2, ((float) scaleBitmapImage.getHeight() - 1) / 2, (Math.min(((float) scaleBitmapImage.getWidth()), ((float) scaleBitmapImage.getHeight())) / 2), Path.Direction.CCW);
canvas.clipPath(path);
Bitmap sourceBitmap = scaleBitmapImage;
canvas.drawBitmap(sourceBitmap, new Rect(0, 0, sourceBitmap.getWidth(), sourceBitmap.getHeight()), new Rect(0, 0, scaleBitmapImage.getWidth(), scaleBitmapImage.getHeight()), null);
return targetBitmap;
}
Since the clipped part is transparent, it will appear as if the actual View is a circle. Also make sure that the bounds of the View are squared (or that adjustViewBounds="true") else you may get visual distortions in terms of width or height.
Pretty sure that's as close to a "rounded View" as you can actually get.
How about the solution give by Romain Guy to use a custom Drawable. You're ImageView will not be round and your source image will be untouched.
class StreamDrawable extends Drawable {
private final float mCornerRadius;
private final RectF mRect = new RectF();
private final BitmapShader mBitmapShader;
private final Paint mPaint;
private final int mMargin;
StreamDrawable(Bitmap bitmap, float cornerRadius, int margin) {
mCornerRadius = cornerRadius;
mBitmapShader = new BitmapShader(bitmap,
Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setShader(mBitmapShader);
mMargin = margin;
}
#Override
protected void onBoundsChange(Rect bounds) {
super.onBoundsChange(bounds);
mRect.set(mMargin, mMargin, bounds.width() - mMargin, bounds.height() - mMargin);
}
#Override
public void draw(Canvas canvas) {
canvas.drawRoundRect(mRect, mCornerRadius, mCornerRadius, mPaint);
}
#Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
#Override
public void setAlpha(int alpha) {
mPaint.setAlpha(alpha);
}
#Override
public void setColorFilter(ColorFilter cf) {
mPaint.setColorFilter(cf);
}
}
You can add rounded corners in a android view with the GradientDrawable.
So ,
GradientDrawable gd = new GradientDrawable();
gd.setColor(Color.TRANSPARENT);
gd.setCornerRadius(15f);
gd.setStroke(1f,Color.BLACK);
yourImageView.setBackground(gd);
SmartImageView extends from ImageView .. so you just have to extend from SmartImageView
Here is a working solution (based on pskink code & smartImageView lib )
Create a new Class
public class RoundedCornersSmartImageView extends SmartImageView{
private int RADIUS = 0;
private RectF mRect;
private Path mClip;
public RoundedCornersSmartImageView(Context context) {
super(context);
init();
}
public RoundedCornersSmartImageView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public RoundedCornersSmartImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
#Override
public void onDraw(Canvas canvas) {
Drawable dr = getDrawable();
if (dr != null) {
mRect.set(dr.getBounds());
getImageMatrix().mapRect(mRect);
mRect.offset(getPaddingLeft(), getPaddingTop());
mClip.reset();
mClip.addRoundRect(mRect, RADIUS, RADIUS, Path.Direction.CCW);
canvas.clipPath(mClip);
super.onDraw(canvas);
}
}
public void setRadius(int radius){
this.RADIUS = radius;
}
private void init(){
mRect = new RectF();
mClip = new Path();
}
}
USAGE
in your layout file your SmartimageView should look like this
<your.package.path.RoundedCornersSmartImageView
android:id="#+id/list_image"
android:layout_width="60dip"
android:layout_height="60dip"
android:src="#drawable/profile_anonyme_thumb"/>
..and init the view in your code this way
RoundedCornersSmartImageView thumb_image=(RoundedCornersSmartImageView) findViewById(R.id.list_image);
thumb_image.setRadius(4);
//SmartImageView methode
thumb_image.setImageUrl(bla.MY_THUMB_URL));
Edit your radius for a round image ..