1

I'm using Android Studio and I would like to be able to pickup am image from the gallery, resize it and make it fit inside a rounded square (of about 300x300px) by maintening the correct aspect ratio. At the moment, I'm able to resize it and display it as a circle.

 FixBitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
                bitmap_to_save = scaleBitmapAndKeepRation(FixBitmap, 320, 320);

                RoundedBitmapDrawable roundDrawable = RoundedBitmapDrawableFactory.create(getResources(), bitmap_to_save);
                roundDrawable.setCircular(true);
                p_avatar.setImageDrawable(roundDrawable);

However, I would like to know if it is possible to make the bitmap look like my attached image. Moreover, it would be important for me to resize the image without losing the original aspect ratio.

enter image description here

It is not exactly a well square rounded figure, so I'm not sure that it is possible to do it in Android.

Please, keep in mind that I dinamycally change the imageview inside the code depending on the user actions. So this is not a static image, I replace the original content with a new one if the user upload a new image.


EDIT 1 on May, 20


This is my XML code for the imageview "avatar":

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/ll_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="loginpackage.social.com.ui.profile.ProfileActivity">

    <include layout="@layout/custom_toolbar_shadow" />

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:fillViewport="true">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center_horizontal"
            android:orientation="vertical"
            android:paddingTop="@dimen/_20sdp">


            <ImageView
                android:id="@+id/avatar"
                android:layout_width="137dp"
                android:layout_height="150dp"
                android:layout_gravity="center"
                android:clickable="true"
                android:paddingBottom="@dimen/_10sdp"
                android:paddingTop="@dimen/_10sdp"
                />


            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="@dimen/_20sdp"
                android:orientation="vertical"
                android:paddingLeft="@dimen/_16sdp"
                android:paddingRight="@dimen/_16sdp">

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="@string/profileActivity_name"
                    android:textSize="@dimen/_14sdp" />

                <EditText
                    android:id="@+id/et_fullname"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="@dimen/_5sdp"
                    android:background="@color/colorWhite"
                    android:hint="@string/signActivity_fullname"
                    android:imeOptions="actionDone"
                    android:inputType="textNoSuggestions"
                    android:maxLines="1"
                    android:padding="@dimen/_10sdp" />

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="@dimen/_10sdp"
                    android:text="@string/profileActivity_email"
                    android:textSize="@dimen/_14sdp" />

                <EditText
                    android:id="@+id/et_email"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="@dimen/_5sdp"
                    android:background="@drawable/editext_back_login"
                    android:hint="@string/mainActivity_email"
                    android:imeOptions="actionNext"
                    android:inputType="textEmailAddress|textNoSuggestions"
                    android:maxLines="1"
                    android:padding="@dimen/_10sdp" />

                <Button
                    android:id="@+id/btn_update"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="@dimen/_20sdp"
                    android:background="@color/colorSignuoBtn"
                    android:text="@string/profileActivity_update"
                    android:textColor="@color/colorWhite"
                    android:textSize="@dimen/_12sdp"
                    android:visibility="invisible" />

                <TextView
                    android:id="@+id/txt_logout"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:layout_marginBottom="@dimen/_10sdp"
                    android:layout_marginTop="@dimen/_20sdp"
                    android:background="@drawable/button_logout_profile"
                    android:foreground="?attr/selectableItemBackgroundBorderless"
                    android:gravity="center"
                    android:paddingBottom="@dimen/_12sdp"
                    android:paddingTop="@dimen/_12sdp"
                    android:text="@string/profileActivity_logout"
                    android:textSize="@dimen/_12sdp" />
            </LinearLayout>
        </LinearLayout>
    </ScrollView>
</LinearLayout>

EDIT 2

At the moment, I'm using Picasso to round the image and it seems to work well. The problem is that I would like to keep always the same picture size (350x350px) and the aspect ratio. How is it possible to do it?

 Transformation transformation = new RoundedTransformationBuilder()
                    .borderColor(Color.GREEN)
                    .borderWidthDp(2)
                    .cornerRadiusDp(15)
                    .oval(false)
                    .build();

            Picasso.get().load("http://www.server.com/uploads/avatars/"+Conts.USERINFO.getId()).transform(transformation).memoryPolicy(MemoryPolicy.NO_CACHE, MemoryPolicy.NO_STORE).networkPolicy(NetworkPolicy.NO_CACHE) .into(p_avatar);

EDIT3:


 <com.makeramen.roundedimageview.RoundedImageView
            xmlns:app="http://schemas.android.com/apk/res-auto"
            android:id="@+id/avatar"
            android:layout_width="160dp"
            android:layout_height="160dp"
            android:src="@drawable/adduserprofile"
            android:scaleType="centerCrop"
            app:riv_border_width="2dip"
            app:riv_border_color="#333333"
            app:riv_mutate_background="true"
            app:riv_oval="false"
            app:riv_corner_radius_bottom_left="20dp"
            app:riv_corner_radius_top_right="20dp"
            />

Why if I set a different value for riv_corner_radius_top_right, then the app crashes? For example, if I set:

 app:riv_corner_radius_bottom_left="20dp"
 app:riv_corner_radius_top_right="10dp"

I get this error:

  E/AndroidRuntime: FATAL EXCEPTION: main
                  Process: loginpackage.social.com, PID: 25495
                  java.lang.RuntimeException: Unable to start activity ComponentInfo{loginpackage.social.com/loginpackage.social.com.ui.profile.ProfileActivity}: android.view.InflateException: Binary XML file line #24: Error inflating class com.makeramen.roundedimageview.RoundedImageView
                      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2689)
                      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2754)
                      at android.app.ActivityThread.access$900(ActivityThread.java:177)
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1448)
                      at android.os.Handler.dispatchMessage(Handler.java:102)
                      at android.os.Looper.loop(Looper.java:145)
                      at android.app.ActivityThread.main(ActivityThread.java:5938)
                      at java.lang.reflect.Method.invoke(Native Method)
                      at java.lang.reflect.Method.invoke(Method.java:372)
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1400)
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1195)
                   Caused by: android.view.InflateException: Binary XML file line #24: Error inflating class com.makeramen.roundedimageview.RoundedImageView
                      at android.view.LayoutInflater.createView(LayoutInflater.java:640)
                      at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:750)
                      at android.view.LayoutInflater.rInflate(LayoutInflater.java:813)
                      at android.view.LayoutInflater.rInflate(LayoutInflater.java:821)
                      at android.view.LayoutInflater.rInflate(LayoutInflater.java:821)
                      at android.view.LayoutInflater.inflate(LayoutInflater.java:511)
                      at android.view.LayoutInflater.inflate(LayoutInflater.java:415)
                      at android.view.LayoutInflater.inflate(LayoutInflater.java:366)
                      at android.support.v7.app.AppCompatDelegateImplV9.setContentView(AppCompatDelegateImplV9.java:287)
                      at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:139)
                      at loginpackage.social.com.ui.profile.ProfileActivity.onCreate(ProfileActivity.java:93)
                      at android.app.Activity.performCreate(Activity.java:6288)
                      at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119)
                      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2642)
                      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2754) 
                      at android.app.ActivityThread.access$900(ActivityThread.java:177) 
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1448) 
                      at android.os.Handler.dispatchMessage(Handler.java:102) 
                      at android.os.Looper.loop(Looper.java:145) 
                      at android.app.ActivityThread.main(ActivityThread.java:5938) 
                      at java.lang.reflect.Method.invoke(Native Method) 
                      at java.lang.reflect.Method.invoke(Method.java:372) 
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1400) 
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1195) 
                   Caused by: java.lang.reflect.InvocationTargetException
                      at java.lang.reflect.Constructor.newInstance(Native Method)
                      at java.lang.reflect.Constructor.newInstance(Constructor.java:288)
                      at android.view.LayoutInflater.createView(LayoutInflater.java:614)
                      at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:750) 
                      at android.view.LayoutInflater.rInflate(LayoutInflater.java:813) 
                      at android.view.LayoutInflater.rInflate(LayoutInflater.java:821) 
                      at android.view.LayoutInflater.rInflate(LayoutInflater.java:821) 
                      at android.view.LayoutInflater.inflate(LayoutInflater.java:511) 
                      at android.view.LayoutInflater.inflate(LayoutInflater.java:415) 
                      at android.view.LayoutInflater.inflate(LayoutInflater.java:366) 
                      at android.support.v7.app.AppCompatDelegateImplV9.setContentView(AppCompatDelegateImplV9.java:287) 
                      at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:139) 
                      at loginpackage.social.com.ui.profile.ProfileActivity.onCreate(ProfileActivity.java:93) 
                      at android.app.Activity.performCreate(Activity.java:6288) 
                      at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119) 
                      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2642) 
                      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2754) 
                      at android.app.ActivityThread.access$900(ActivityThread.java:177) 
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1448) 
                      at android.os.Handler.dispatchMessage(Handler.java:102) 
                      at android.os.Looper.loop(Looper.java:145) 
                      at android.app.ActivityThread.main(ActivityThread.java:5938) 
                      at java.lang.reflect.Method.invoke(Native Method) 
                      at java.lang.reflect.Method.invoke(Method.java:372) 
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1400) 
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1195) 
                   Caused by: java.lang.IllegalArgumentException: Multiple nonzero corner radii not yet supported.
                      at com.makeramen.roundedimageview.RoundedDrawable.setCornerRadius(RoundedDrawable.java:507)
                      at com.makeramen.roundedimageview.RoundedImageView.updateAttrs(RoundedImageView.java:368)
                      at com.makeramen.roundedimageview.RoundedImageView.updateDrawableAttrs(RoundedImageView.java:318)
                      at com.makeramen.roundedimageview.RoundedImageView.<init>(RoundedImageView.java:163)
                      at com.makeramen.roundedimageview.RoundedImageView.<init>(RoundedImageView.java:86)
                      at java.lang.reflect.Constructor.newInstance(Native Method) 
                      at java.lang.reflect.Constructor.newInstance(Constructor.java:288) 
                      at android.view.LayoutInflater.createView(LayoutInflater.java:614) 
                      at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:750) 
                      at android.view.LayoutInflater.rInflate(LayoutInflater.java:813) 
                      at android.view.LayoutInflater.rInflate(LayoutInflater.java:821) 
                      at android.view.LayoutInflater.rInflate(LayoutInflater.java:821) 
                      at android.view.LayoutInflater.inflate(LayoutInflater.java:511) 
                      at android.view.LayoutInflater.inflate(LayoutInflater.java:415) 
                      at android.view.LayoutInflater.inflate(LayoutInflater.java:366) 
                      at android.support.v7.app.AppCompatDelegateImplV9.setContentView(AppCompatDelegateImplV9.java:287) 
                      at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:139) 
                      at loginpackage.social.com.ui.profile.ProfileActivity.onCreate(ProfileActivity.java:93) 
                      at android.app.Activity.performCreate(Activity.java:6288) 
                      at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119) 
                      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2642) 
                      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2754) 
                      at android.app.ActivityThread.access$900(ActivityThread.java:177) 
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1448) 
                      at android.os.Handler.dispatchMessage(Handler.java:102) 
                      at android.os.Looper.loop(Looper.java:145) 
                      at android.app.ActivityThread.main(ActivityThread.java:5938) 
                      at java.lang.reflect.Method.invoke(Native Method) 
                      at java.lang.reflect.Method.invoke(Method.java:372) 
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1400) 
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1195) 
Marcus Barnet
  • 2,083
  • 6
  • 28
  • 36
  • 1
    ... decrease the corner radius? `radius = 1/x * square_size`, with x=2 would give you a circle. A greater value of x (resulting in a smaller radius) would give you a rounded square. i.e.: radius = .5 * square_size = circle, radius = .1 * square_size = rounded square. Being .5 = 1/2 and .1 = 1/10, obviously enough. – Phantômaxx May 19 '18 at 14:08
  • how can i change the corner radius in Android? – Marcus Barnet May 19 '18 at 16:02
  • In an xml drawable it's [easy-peasy](https://developer.android.com/guide/topics/resources/drawable-resource#Shape). Programmatically, it can be a little [harder](https://developer.android.com/reference/android/graphics/drawable/shapes/RoundRectShape). But manageable, at last ;) – Phantômaxx May 19 '18 at 16:07
  • 1
    thank you for your help! I need to study it very well before using it. It doesn't seem to be easy to integrate this solution in my current code. – Marcus Barnet May 19 '18 at 16:48
  • Maybe simplify your life and use an xml drawable? – Phantômaxx May 19 '18 at 16:49
  • At the moment, I'm using Picasso to round the image and it seems to work well. The problem is that I would like to **keep always the same picture size** (350x350px) and the **aspect ratio**. How is it possible to do it? - See EDIT2 in the original question – Marcus Barnet May 20 '18 at 16:18

2 Answers2

1

You should not give your time to manage these types of logics if you are working on projects in company.

Instead you can just use libraries which have already done great work. See https://github.com/vinc3m1/RoundedImageView

Your ImageView will be like

<com.makeramen.roundedimageview.RoundedImageView
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/imageView1"
        android:src="@drawable/photo1"
        android:scaleType="centerCrop"
        app:riv_corner_radius="30dip"
        app:riv_border_width="2dip"
        app:riv_border_color="#333333"
        app:riv_mutate_background="true"
        app:riv_tile_mode="repeat"
        app:riv_oval="true" />

and dependency

repositories {
    mavenCentral()
}

dependencies {
    compile 'com.makeramen:roundedimageview:2.3.0'
}

Update

You seem new to android, if you don't understand id and src, no worries!

Basically id is an unique id that you have created and you refer to imageView1 if you do findViewById(R.id.imageView1) in your java code.

for more info about id : Difference between "@id/" and "@+id/" in Android

src is the source image file for that image, that is located in your drawables directory.

About your issue

You can use different ImageView ScaleType that matches your requirement. I think you use android:scaleType="centerCrop" that fit your image at imageView.

I also edited scaleType in above answer. If that does not fit your requirement you can use any of these scale type

Update 2 for setting width and height, you can set layout_width and layout_height attribute. like below.

 <com.makeramen.roundedimageview.RoundedImageView
            xmlns:app="http://schemas.android.com/apk/res-auto"
            android:id="@+id/imageView1"
            android:src="@drawable/photo1"
            android:scaleType="centerCrop"
            app:riv_corner_radius="30dip"
            app:riv_border_width="2dip"
            app:riv_border_color="#333333"
            app:riv_mutate_background="true"
            app:riv_tile_mode="repeat"
            app:riv_oval="true" 
            android:layout_width="350dp"
            android:layout_height="350dp"/>

see What is the difference between "px", "dip", "dp" and "sp"? for more detail about sp, dp, px in android.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Khemraj Sharma
  • 57,232
  • 27
  • 203
  • 212
  • It extends `ImageView` so `setImageBitmap()`, `setImageDrawable()`, `setImageResource()` are same as `ImageView`. – Khemraj Sharma May 20 '18 at 06:10
  • 1
    **[this](https://github.com/siyamed/android-shape-imageview)** library is even better. – Phantômaxx May 20 '18 at 06:48
  • Yes there would be always better option, but above answer library also fulfill his requirement. – Khemraj Sharma May 20 '18 at 06:51
  • in my xml layout, I have this code for my image: `` How should I modify it if I want to use the Shape Image View or the Kling Klang's solution? Thank you. I edit the question by adding the xmlcode. – Marcus Barnet May 20 '18 at 15:52
  • @Khemraj thank you for your support and your explaination. I'm trying this code and check id it is possible to have a picture shape like the one I attached in my first question. Moreover, Is it possible to set a fixed size 350x350px for each picture? user can upload image with different size but I would like to make them all fit 350x350px. – Marcus Barnet May 21 '18 at 10:11
  • @Khemraj really thank you for all your efforts! I added EDIT3 in my question, since it is working very well right now, but if I define different values for the corners, the app crashes even if it gives no error during the building. – Marcus Barnet May 21 '18 at 10:35
  • 1
    This stacktrace is not enough. Can you post full stacktrace? – Khemraj Sharma May 21 '18 at 10:38
  • I added the full error trace in EDIT3 in my first question. Thank you. – Marcus Barnet May 21 '18 at 10:47
  • 1
    @MarcusBarnet See this issue – Khemraj Sharma May 21 '18 at 10:52
  • 1
    You can not set multiple corner radius in this imageView till now. You have to use same radius. – Khemraj Sharma May 21 '18 at 10:53
  • Thank you, @Khemraj! I checked your answer as the correct one. I really appreciated your effort. – Marcus Barnet May 21 '18 at 14:43
  • I suggest you work with some android developer, your work is negligible without any training or guidance. – Khemraj Sharma May 21 '18 at 15:36
1

I wrote a MaskView that lets you mask images to any shape, including holes in the middle and partial transparency. It's a lot of code, and I wrote it a long time ago so I wouldn't even use it myself without reviewing it. But the essence of it is an ImageView that takes an alpha mask. When it draws itself, it draws two bitmaps for itself and whatever is behind it, and combines them using the mask.

enter image description here

Kevin Krumwiede
  • 9,868
  • 4
  • 34
  • 82