I have a user icon in each row in a lift view. I'd like one corner rounded. Here is what I have and it does nothing:
<ImageView
android:background="#drawable/profile_widget_selector"
android:id="#+id/ivTopUserPP"
android:layout_width="65dp"
android:layout_height="65dp"
android:baselineAlignBottom="#drawable/profile_pic_shape"
android:src="#drawable/usericon" />
profile_pic_shape.xml
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<solid android:color="#bbbbbb" />
<stroke
android:width="1dp"
android:color="#bbb" />
<padding
android:bottom="1dp"
android:left="1dp"
android:right="1dp"
android:top="1dp" />
<corners android:topLeftRadius="40dp" />
</shape>
You can use a Universal Image Loader.
https://github.com/nostra13/Android-Universal-Image-Loader.
Can be used to display bitmaps with rounded corners. Check the Link above.
In your custom adapter constructor
File cacheDir = StorageUtils.getOwnCacheDirectory(a, "your folder");
// Get singletone instance of ImageLoader
imageLoader = ImageLoader.getInstance();
// Create configuration for ImageLoader (all options are optional)
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(a)
// You can pass your own memory cache implementation
.discCache(new UnlimitedDiscCache(cacheDir)) // You can pass your own disc cache implementation
.discCacheFileNameGenerator(new HashCodeFileNameGenerator())
.enableLogging()
.build();
// Initialize ImageLoader with created configuration. Do it once.
imageLoader.init(config);
options = new DisplayImageOptions.Builder()
.showStubImage(R.drawable.stub_id)//display stub image
.cacheInMemory()
.cacheOnDisc()
.displayer(new RoundedBitmapDisplayer(20)) //rounded corner bitmap
.build();
In your getView()
ImageView image=(ImageView)vi.findViewById(R.id.imageview);
imageLoader.displayImage(imageurl, image,options);//provide imageurl, imageview and options
You can configure with other options to suit your needs.
Romain guys image with rounded corners # http://www.curious-creature.org/2012/12/11/android-recipe-1-image-with-rounded-corners/
Found the below # How to make an ImageView with rounded corners?
http://ruibm.com/?p=184.
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;
}
}
Related
I am trying to make my ImageView round. I have written the following code to make it appear round but somehow it is still showing square ImageView. [Using picasso to fetch image]
Java code:
ImageView iv = (ImageView) addLinkDialog.findViewById(R.id.group_icon_jsoup);
Picasso.with(getBaseContext()).load(GroupImageUrl).into(iv);
iv.setBackgroundResource(R.drawable.icon_img);
ImageView code:
<ImageView
android:id="#+id/group_icon_jsoup"
android:layout_width="75dp"
android:layout_height="75dp"
android:layout_gravity="center"
android:layout_margin="8dp"
android:background="#drawable/icon_img" />
#drawable/icon_img.xml:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:drawable="#drawable/circle"/>
</layer-list>
#drawable/circle.xml
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:innerRadius="0dp"
android:shape="ring"
android:thicknessRatio="1.9"
android:useLevel="false" >
<solid android:color="#android:color/transparent" />
<stroke
android:width="10dp"
android:color="#android:color/white" />
</shape>
Why not using third party ?
Try this code
Bitmap picture = BitmapFactory.decodeResource(getResources(), R.mipmap.add_image);
ImageView imageView = (ImageView) findViewById(R.id.imgProfilePicture);
imageView.setImageBitmap(getRoundedBitmap(picture));
public Bitmap getRoundedBitmap(Bitmap bitmap){
Bitmap circleBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
BitmapShader shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
Paint paint = new Paint();
paint.setShader(shader);
paint.setAntiAlias(true);
Canvas c = new Canvas(circleBitmap);
c.drawCircle(bitmap.getWidth() / 2, bitmap.getHeight() / 2, bitmap.getWidth() / 2, paint);
return circleBitmap;
}
Your xml file
<de.hdodenhof.circleimageview.CircleImageView
android:id="#+id/imgProfilePicture"
android:layout_width="110dp"
android:layout_height="110dp"
android:layout_marginBottom="20dp"
app:civ_border_width="3dp"
app:civ_border_color="#color/light_gray" />
and add this in build.gradle
compile 'de.hdodenhof:circleimageview:2.1.0'
Cirular ImageView Done !
Do you want to use only code or you are ok with library too? If you are ok with library may I suggest using this library, helped me a lot. If you don't want to use library, you can use RoundedBitmapDrawable:
RoundedBitmapDrawable drawable =
RoundedBitmapDrawableFactory.create(context.getResources(), bitmap)
drawable.setCircular(true);
Use this drawable in your ImageView.
Major problem will be when you use Picasso to set image again to set to imageView view bounds not to the its background that you create.
If you programmatically set a one it will override your background!
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="false">
<shape android:shape="oval">
<solid android:color="#color/colorPrimary"/>
</shape>
</item>
</selector>
You can set this as background of your view.Then try to use view.setBackgroundResource(R.drawable.icon_img); . you will notice the change!
You can go through Add a background image to shape in xml Android
Mask ImageView with round corner background
to check the various ways people tried out here!
But with Picasso you can do this directly with out other 3rd parties.
final ImageView imageView = (ImageView) findViewById(R.id.group_icon_jsoup);
Picasso.with(YourActivity.this).load("http://i.imgur.com/DvpvklR.png")
.resize(100, 100)
.into(imageView, new Callback() {
#Override
public void onSuccess() {
Bitmap imageBitmap = ((BitmapDrawable) imageView.getDrawable()).getBitmap();
RoundedBitmapDrawable imageDrawable = RoundedBitmapDrawableFactory.create(getResources(), imageBitmap);
imageDrawable.setCircular(true);
imageDrawable.setCornerRadius(Math.max(imageBitmap.getWidth(), imageBitmap.getHeight()) / 2.0f);
imageView.setImageDrawable(imageDrawable);
}
#Override
public void onError() {
imageView.setImageResource(R.drawable.amanda);
}
});
Hello #Surjan here is the code which help to create a image in Any shape which you want only you need image of your choice shape with transparent and combination of any other color, following was the example :
protected Bitmap getPinnedImage(Bitmap original, int shapeImage) {
if (original == null) {
original = BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_round_shape);
}
Bitmap mask = BitmapFactory.decodeResource(context.getResources(), shapeImage);
original = Bitmap.createScaledBitmap(original, mask.getWidth(), mask.getHeight(), true);
Bitmap result = Bitmap.createBitmap(mask.getWidth(), mask.getHeight(), Bitmap.Config.ARGB_8888);
Canvas mCanvas = new Canvas(result);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
mCanvas.drawBitmap(original, 0, 0, null);
mCanvas.drawBitmap(mask, 0, 0, paint);
paint.setXfermode(null);
return result;
}
Here is the tow parameter first one is your original bitmap and second one is the your shape drawable, like following was the pin shape
now passing after this drawable you can get your image in pin shape no need to access any third party library.
Try this,
ImageView iv = (ImageView) addLinkDialog.findViewById(R.id.group_icon_jsoup);
Picasso.with(getBaseContext()).load(GroupImageUrl).transform(new RoundedTransformation(5,15, Color.parseColor("#27a3cb"))).fit().into(iv);
public class RoundedTransformation implements Transformation {
private int mBorderSize;
private int mCornerRadius = 0;
private int mColor;
public RoundedTransformation(int borderSize, int color) {
this.mBorderSize = borderSize;
this.mColor = color;
}
public RoundedTransformation(int borderSize, int cornerRadius, int color) {
this.mBorderSize = borderSize;
this.mCornerRadius = cornerRadius;
this.mColor = color;
}
#Override
public Bitmap transform(Bitmap source) {
int width = source.getWidth();
int height = source.getHeight();
Bitmap image = Bitmap.createBitmap(width, height, source.getConfig());
Canvas canvas = new Canvas(image);
canvas.drawARGB(0, 0, 0, 0);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
Rect rect = new Rect(0, 0, width, height);
if(this.mCornerRadius == 0) {
canvas.drawRect(rect, paint);
}
else {
canvas.drawRoundRect(new RectF(rect),this.mCornerRadius, this.mCornerRadius, paint);
}
paint.setXfermode(new PorterDuffXfermode((PorterDuff.Mode.SRC_IN)));
canvas.drawBitmap(source, rect, rect, paint);
Bitmap output;
if(this.mBorderSize == 0) {
output = image;
}
else {
width = width + this.mBorderSize * 2;
height = height + this.mBorderSize * 2;
output = Bitmap.createBitmap(width, height, source.getConfig());
canvas.setBitmap(output);
canvas.drawARGB(0, 0, 0, 0);
rect = new Rect(0, 0, width, height);
paint.setXfermode(null);
paint.setColor(this.mColor);
paint.setStyle(Paint.Style.FILL);
canvas.drawRoundRect(new RectF(rect), this.mCornerRadius, this.mCornerRadius, paint);
canvas.drawBitmap(image, this.mBorderSize, this.mBorderSize, null);
}
if(source != output) source.recycle();
return output;
}
#Override
public String key() {
return "bitmapBorder(" +
"borderSize=" + this.mBorderSize + ", " +
"cornerRadius=" + this.mCornerRadius + ", " +
"color=" + this.mColor +")";
}
}
I am using this code to get top rounded corners of bitmap
public static void setTopRounded(Bitmap workingBitmap , int w, int h, ImageView v,Context context)
{
Bitmap bmp = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(bmp);
Shader shader = new BitmapShader(workingBitmap, Shader.TileMode.MIRROR,
Shader.TileMode.MIRROR);
Paint paint = new Paint(Paint.FILTER_BITMAP_FLAG);
paint.setAntiAlias(true);
paint.setShader(shader);
RectF rec = new RectF(0, 0, w, h - 20);
c.drawRect(new RectF(0, 20, w, h), paint);
c.drawRoundRect(rec, 10, 10, paint);
v.setBackgroundDrawable(new BitmapDrawable(context.getResources(), bmp));
}
and my XML code for Image view is
<ImageView
android:layout_height="140dp"
android:layout_width="match_parent"
android:id="#+id/profileIV"
android:visibility="gone"
android:scaleType="centerCrop" />
now the problem is by setting
v.setBackgroundDrawable(new BitmapDrawable(context.getResources(), bmp)),
android:scaleType="centerCrop"
property did not work and if i use
v.setImageDrawable(new BitmapDrawable(context.getResources(), bmp))
then scale type works but the image does not get rounded.
What i am doing wrong?
Try v.setImageBitmap(bmp) instead
/**
* This method used for bitmap compress and rounded corner
* #param Bitmap object
* #param pixels
* #return nothing
*/
public static Bitmap getRoundedRectBitmap(final Bitmap bitmap,final int pixels)
{
int color;
float roundPx;
final Bitmap result = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
final Canvas canvas = new Canvas(result);
color = 0xff424242;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
final RectF rectF = new RectF(rect);
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 result;
}
//call the above method like this
profileImage.setImageBitmap(getRoundedRectBitmap(bitmap, 50));
I found the answer. I did not change any thing. Using the same function for top rounded corners image and use bitmap as background in image view. But now doing CenterCrop in code for imageView using ThumbnailUtils
First i use below function to get scaled CenterCroped image
Bitmap resizedProfileBitmap = ThumbnailUtils.extractThumbnail(profileBitmap, voucherTitleRLT.getWidth(), height);
and then use top rounded function to get set top rounded center croped image as background of imageview like below
setTopRounded(resizedProfileBitmap, resizedProfileBitmap.getWidth(), resizedProfileBitmap.getHeight(), profileIV, thisContext);
You can do this in XML by creating a Shape Drawable and setting it as the background on your ImageView. This article explains how: http://www.techrepublic.com/article/pro-tip-round-corners-on-an-android-imageview-with-this-hack/#
Your shape drawable can look like this:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#00ffffff" />
<padding
android:left="1dp"
android:top="1dp"
android:right="1dp"
android:bottom="1dp" />
<corners
android:topLeftRadius="6dp"
android:topRightRadius="6dp"
android:bottomLeftRadius="0.1dp"
android:bottomRightRadius="0.1dp" />
<stroke
android:width="6dp"
android:color="#ffffffff" />
i was searching for past one day and i was not successful .
i get the image from API , and i download it to a bitmap file using the following code .
private Bitmap DownloadImage(String URL)
{
Bitmap bitmap = null;
InputStream in = null;
try
{
in = OpenHttpConnection(URL);
bitmap = BitmapFactory.decodeStream(in);
in.close();
}
catch (IOException e1)
{
e1.printStackTrace();
}
return bitmap;
}
private InputStream OpenHttpConnection(String urlString) throws IOException
{
InputStream in = null;
int response = -1;
URL url = new URL(urlString);
URLConnection conn = url.openConnection();
if (!(conn instanceof HttpURLConnection))
throw new IOException("Not an HTTP connection");
try
{
HttpURLConnection httpConn = (HttpURLConnection) conn;
httpConn.setAllowUserInteraction(false);
httpConn.setInstanceFollowRedirects(true);
httpConn.setRequestMethod("GET");
httpConn.connect();
response = httpConn.getResponseCode();
if (response == HttpURLConnection.HTTP_OK)
{
in = httpConn.getInputStream();
}
}
catch (Exception ex)
{
throw new IOException("Error connecting");
}
return in;
}
And i get the image as a square and i want to crop the four corners and make it to circular image . Is there any possible way to achieve ?
Any related answers are welcomed . Thanks in advance .
Once the bitmap is retrieved RoundedBitmapDrawableFactory can be used to generate a RoundedBitmapDrawable from the v4 Support Library. That Drawable can then be applied to an ImageView or directly drawn to a Canvas.
// Create the RoundedBitmapDrawable.
RoundedBitmapDrawable roundDrawable = RoundedBitmapDrawableFactory.create(getResources(), bitmap);
roundDrawable.setCircular(true);
// Apply it to an ImageView.
ImageView imageView = (ImageView)findViewById(R.id.imageView);
imageView.setImageDrawable(roundDrawable);
// Alternatively, draw it to an canvas (e.g. in onDraw where a Canvas is available).
// setBounds since there's no View handling size and positioning.
roundDrawable.setBounds(left, top, right, bottom);
roundDrawable.draw(canvas);
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
DrawingView dv = new DrawingView(this);
setContentView(dv);
}
class DrawingView extends View {
Bitmap bitmap;
public DrawingView(Context context) {
super(context);
bitmap = BitmapFactory.decodeResource(context.getResources(),
R.drawable.glossy_overlay);
}
#Override
public void onDraw(Canvas canvas) {
Paint paint = new Paint();
// paint.setColor(Color.CYAN);
canvas.drawBitmap(getclip(), 30, 20, paint);
}
public Bitmap getclip() {
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());
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
// paint.setColor(color);
canvas.drawCircle(bitmap.getWidth() / 2,
bitmap.getHeight() / 2, bitmap.getWidth() / 2, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return output;
}
}
}
use the function below to draw a circle on bitmap and then set the circled bitmap to imageView
public static Bitmap getClip(Bitmap bitmap) {
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
canvas.drawCircle(bitmap.getWidth() / 2f, bitmap.getHeight() / 2f,
bitmap.getWidth() / 2f, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return output;
}
Note: Dividing numbers must be float
Roman Nurik propose a very direct use of shaders to do things like that, with a custom drawable.
I change the code a bit to make an oval image and tested myself. The effect and performance are really good:
public class StreamDrawable extends Drawable {
private static final boolean USE_VIGNETTE = true;
private final RectF mRect = new RectF();
private final BitmapShader mBitmapShader;
private final Paint mPaint;
private final int mMargin;
public StreamDrawable(Bitmap bitmap, int margin) {
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);
if (USE_VIGNETTE) {
RadialGradient vignette = new RadialGradient(
mRect.centerX(), mRect.centerY() * 1.0f / 0.7f, mRect.centerX() * 1.3f,
new int[] { 0, 0, 0x7f000000 }, new float[] { 0.0f, 0.7f, 1.0f },
Shader.TileMode.CLAMP);
Matrix oval = new Matrix();
oval.setScale(1.0f, 0.7f);
vignette.setLocalMatrix(oval);
mPaint.setShader(
new ComposeShader(mBitmapShader, vignette, PorterDuff.Mode.SRC_OVER));
}
}
#Override
public void draw(Canvas canvas) {
canvas.drawOval(mRect, 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);
}
}
This can be simply done in xml, Please see my answer here:
https://stackoverflow.com/a/18287979/665930
<RelativeLayout
android:id="#+id/icon_layout"
android:layout_width="#dimen/icon_mask"
android:layout_height="#dimen/icon_mask"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" >
<ImageView
android:id="#+id/icon"
android:layout_width="#dimen/icon"
android:layout_height="#dimen/icon"
android:layout_centerInParent="true"
android:scaleType="fitXY" >
</ImageView>
<ImageView
android:id="#+id/icon_mask"
android:layout_width="#dimen/icon_mask"
android:layout_height="#dimen/icon_mask"
android:layout_centerInParent="true"
android:background="#drawable/circle"
android:scaleType="fitXY" >
</ImageView>
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval" >
<gradient android:startColor="#00FFFFFF" android:endColor="#00FFFFFF"
android:angle="270"/>
<stroke android:width="10dp" android:color="#FFAAAAAA"/>
I tried the solutions above but none worked well for me. This is because my phone camera don't take square image but just rectangle images. So, I make some changes in the #actsai solution to always take the minor dimension and then crop the image in a circle:
public static Bitmap getBitmapClip(Bitmap bitmap) {
int maxLenth = bitmap.getWidth() <= bitmap.getHeight() ? bitmap.getWidth() : bitmap.getHeight();
Bitmap output = Bitmap.createBitmap(maxLenth,
maxLenth, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, maxLenth, maxLenth);
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
canvas.drawCircle(maxLenth / 2, maxLenth / 2,
maxLenth / 2, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return output;
}
I used the following scale property to fill my ImageView with the new bitmap:
<ImageView
android:id="#+id/iv_photo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:scaleType="fitXY" />
After hunting lot of answers I came up with this small hack which exploits FrameLayout(overlays child views as a stack) and stroke attribute of oval-shape. This can be done simply in XML without much hassle and third party libraries.
Create new Layout resource file "circle_image.xml" under res/layout directory.
Add a new FrameLayout as the root view in the circle_image.xml.
Create an ImageView (base/background) to hold your Image or Icon which you want to crop as the first child in the FrameLayout.
Create an ImageView (mask/foreground) to hold the shape(oval made into circle with size attribute having same height and width) that masks the background image as the second/last child inside the FrameLayout.
Note:
our idea here is to exclude the area around the circle and display the contents of the image that is visible inside the circle)
Create new Drawable resource file "circle_mask.xml" under res/drawable directory.
Add new shape with android:shape="oval" in the circle_mask.xml.
Add size tag for the shape to specify height and width which must be equal(to make it a circle) and should match that of its parent FrameLayout.
Add solid tag for the shape to specify the transparency inside the circle.
10.Add stroke tag for the shape so that there will be a ring of particular width(android:width) with the color specified by the android:color attribute.
Note:
a. The color(stroke color) specified in the stoke tag is the MaskColor/BackgroundColor around our cropped image. since I wanted this color to be same as that of my base view which was a cardView. I used the same color "white".
b. The width (stroke width) is set to a huge value such that it is too thick with enough space for our cropped image in the centre.
c. The ImageView(top mask layer) created in Step-4 is also exploited by specifying a huge dimension that is much larger than its parent FrameLayout making it expand outside the FrameLayout dimensions. This fills up the area which we are interested in masking with the color of large stroke width ring.
circle_image.xml
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/icon_layout"
android:layout_width="64dp"
android:layout_height="64dp">
<ImageView
android:id="#+id/iv_profile_pic"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/ic_launcher_background"
android:contentDescription="TODO"/>
<ImageView
android:layout_width="90dp"
android:layout_height="90dp"
android:layout_gravity="center"
android:background="#drawable/circle"
android:scaleType="fitXY" >
</ImageView>
</FrameLayout>
circle_mask.xml
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<size android:width="64dp"
android:height="64dp"/>
<solid android:color="#android:color/transparent"/>
<stroke
android:width="18dp"
android:color="#android:color/white" />
</shape>
I refer to this question which links to this article on how to create rounded corners on an image.
It works fine for image I am downloading from the web, but when I read the image from the Resources/Drawable folder the image is not getting rounded.
When getting image from the web I use:
Bitmap img = BitmapFactory.decodeStream(inputStream);
And when decoding from resources I use:
Bitmap img = BitmapFactory.decodeResource(ctx.getResources(), R.drawable.profile_photo);
When decoding from resources the returned bitmap is not null.
Any ideas on where I am going wrong with this one?
Add a "shape"(XML in drawable).
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#ffffffff"/>
<stroke android:width="3dp"
android:color="#ff000000"
/>
<padding android:left="1dp"
android:top="1dp"
android:right="1dp"
android:bottom="1dp"
/>
<corners android:bottomRightRadius="7dp" android:bottomLeftRadius="7dp"
android:topLeftRadius="7dp" android:topRightRadius="7dp"/>
& use this shape with your drawable. or use this code
public static Bitmap getRoundedCornerBitmap(Bitmap bitmap) {
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 = 12;
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;
}
I just figured out the problem was due to the input images being different resolutions.
The image coming from resources was much bigger than the web and therefore I needed to increase the radius size to get the rounding effect.
I have an XML drawable file with a stroke, and I also have several bitmaps which I want to apply the stroke to. I tried calling Drawable.draw(canvas), but it throws IllegalStateException
stroke XML:
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke android:width="3dp"
android:color="#ffffffff"/>
</shape>
Drawing code:
Drawable strokeDrawable = getResources().getDrawable(R.drawable.stroke);
Bitmap bmp1 = BitmapFactory.decodeResource(getResources(), R.drawable.bmp1);
Canvas canvas = new Canvas(bmp1);
strokeDrawable.draw(canvas);
How should I do this?
Solution:
final int STROKE_WIDTH = 3;
Bitmap copy = Bitmap.createBitmap(bmp1.getWidth() + STROKE_WIDTH * 2, bmp1.getHeight() + STROKE_WIDTH * 2, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(copy);
strokeDrawable.setBounds(0, 0, copy.getWidth(), copy.getHeight());
strokeDrawable.draw(canvas);
canvas.drawBitmap(bmp1, STROKE_WIDTH, STROKE_WIDTH, null);
bmp1.recycle();
bmp1 = copy;