Marcus Barnet
Marcus Barnet

Reputation: 2103

How to fit a bitmap in a rounded square?

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 maintaining 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 dynamically 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);

EDIT #3

 <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) 

Upvotes: 1

Views: 1039

Answers (2)

Khemraj Sharma
Khemraj Sharma

Reputation: 58934

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.

Upvotes: 1

Kevin Krumwiede
Kevin Krumwiede

Reputation: 10288

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

Upvotes: 1

Related Questions