Android: How To Fix Blurry Google Profile Image Taken From Firebase?
Asked Answered
H

6

6

The scenario:

I am building an app that allows the user to sign in using their Google account, it's worth noting that this is done using Firebase authentication.

The problem:

The user signs in perfectly but whenever i get their profile picture it is returned fine but it's very blurry.

I've researched and found some sites mentioning to change the resolution of the Google profile image but I'm not sure if that's possible. I know Facebook has a graph that allows for you to manipulate the URL of the profile image to change the resolution but I'm not sure how to improve the resolution of the profile image via Google.

I've posted a screenshot of the blurry image below:

enter image description here

This is the XML code for the ImageView that I'm loading the profile image in:

<de.hdodenhof.circleimageview.CircleImageView
                xmlns:app="http://schemas.android.com/apk/res-auto"
                android:id="@+id/image_view_profile_pic"
                android:layout_width="96dp"
                android:layout_height="96dp"
                android:layout_gravity="center_horizontal"
                android:layout_marginTop="36dp"
                android:src="@drawable/app_bar_tool_bar_bg"
                app:civ_border_width="2dp"
                app:civ_border_color="#FFFFFFFF"
                  android:contentDescription="@string/content_description_profile_picture" />

This is the code I used to get the profile image from Google via Firebase:

private void getUserProfileContent() {

        // Check if the user is signed in
        if (mUser != null) {
            for (UserInfo profile : mUser.getProviderData()) {

                // Profile photo url
                Uri photoUrl = profile.getPhotoUrl();

                // Load user's profile photo from their signed-in provider into the image view
                Glide.with(ProfileActivity.this)
                        .load(photoUrl)
                        .into(mProfilePic);
            }
        }
    }

This is the code to get the currently authenticated user:

// Variable declaration
private FirebaseUser mUser;

// Initializatioin in onCreate method
mUser = FirebaseAuth.getInstance().getCurrentUser();

Then of course, I call the above method in the onCreate method so it gets executed, like so:

getUserProfileContent();

I have read on this site that Google URLs can be manipulated to change the size of an image:

Details about Google's "magic" URL

Also, I've seen this site mentioning something similar about profile picture being blurry:

Firebase Google Group: Profile picture blurry

As it relates to the second link I haven't quite wrapped my head around how to carry out what they've suggested.

Hannus answered 3/1, 2018 at 21:14 Comment(2)
Need more info than that, how is the ImageView configured, do you use a library to load the image? Post the code and someone may be able to help.Camelback
So I have added more details to the question above. @patrick-ivHannus
H
11

I solved my own problem, I will explain in full detail, see below.

Solution:

This is the newly modified code to my method in the question above, this is the fix:

private void getUserProfileContent() {

        // Check if the user is signed in
        if (mUser != null) {
            for (UserInfo profile : mUser.getProviderData()) {

                // Get the profile photo's url
                Uri photoUrl = profile.getPhotoUrl();

                // Variable holding the original String portion of the url that will be replaced
                String originalPieceOfUrl = "s96-c/photo.jpg";

                // Variable holding the new String portion of the url that does the replacing, to improve image quality
                String newPieceOfUrlToAdd = "s400-c/photo.jpg";

                // Check if the Url path is null
                if (photoUrl != null) {

                    // Convert the Url to a String and store into a variable
                    String photoPath = photoUrl.toString();

                    // Replace the original part of the Url with the new part
                    String newString = photoPath.replace(originalPieceOfUrl, newPieceOfUrlToAdd);

                    // Load user's profile photo from their signed-in provider into the image view (with newly edited Url for resolution improvement)
                    Glide.with(ProfileActivity.this)
                            .load(newString)
                            .into(mProfilePic);

                } // End if
            } // End if
        }

Explanation:

The code is self explanatory but for the sole purpose of clarity for many others who were having issues with this, I basically swapped out the part of the original Url that I retrieved from Google that specified the image's resolution with a higher resolution of my own.

Replaced this "s96-c/photo.jpg" with "s400-c/photo.jpg"

I have provided a screenshot below with TextViews displaying:

  1. Url path of the original Url retrieved from Google (this one has the s96-c in its url)

  2. Url path of the newly modified Url by me (this one has the s400-c in its url)

  3. Original Url retrieved from Google with toString() method called on it. This is the third Url in the screenshot with s96-c

  4. Newly modified Url by me with toString() method called on it. This is the fourth Url (similarly to the 3rd Url in the screenshot this Url has s96-c in its Url String)

In that order

Note:

I wanted to do an in depth explanation with this answer because I wanted to show that even though the string with low res was replaced with high res version, you'll notice the last TextView displays in its Url s96-c and the second-to-last Url (granted you're looking from top to bottom) displays the exact same thing, s96-c

BUT

The resolution indeed improved, so my theory is that even though the resolution improved, by me using a higher value, Google's system returned the improved image with a size of s96-c regardless (Let me know if anyone has a more concrete theory)

Screenshot of profile image with the blurriness fixed (improved resolution):

Screenshot of improved resolution of profile photo and of the Urls and their differences behind the scenes.

Anyway there you have it, I wanted to show a screenshot with the Urls and their differences so that I can explain how everything was happening, for anyone who was curious.

I hope this helps many others, because the blurry Google user profile image was a very inconvenient problem for myself.

Hannus answered 4/1, 2018 at 7:8 Comment(2)
Is there any documentation on the limit of the resolution or quota limitations?Estradiol
Seems like less than 25 doesn't work.Paronychia
P
2

In my case, inside of the HTML of my Ionic4 component I used:

<img class="avatar" [src]="user.photoURL + '?height=150'">

Adding the height parameter to the end of the URL worked for me.

Priestley answered 22/2, 2019 at 2:23 Comment(0)
Q
2

Easy Fix

Just replace s96-c with s400-c or any other like s300-c

from the image url you get from google.

Example:

Here you can easily see the difference..

Look at the end of url.

https://lh4.googleusercontent.com/-C0Mqxb50Hxg/AAAAAAAAAAI/AAAAAAAADcw/xuG-pk0PzaI/s96-c/photo.jpg

https://lh4.googleusercontent.com/-C0Mqxb50Hxg/AAAAAAAAAAI/AAAAAAAADcw/xuG-pk0PzaI/s400-c/photo.jpg

Qp answered 26/6, 2019 at 6:20 Comment(0)
C
0

I feel the code is much clearer this way

 private void onSignedInInitialize(FirebaseUser user) {
    if(user.getDisplayName() != null && user.getDisplayName().length() > 0)
    {
       usernameText.setText(user.getDisplayName());
    }

    String photoUrl;
    String provider = user.getProviders().get(0);
    if (provider.equals("facebook.com")) {
        photoUrl = user.getPhotoUrl() + "?height=500";
    }
    else if(provider.equals("google.com"))
    {
        photoUrl = user.getPhotoUrl().toString();

        //Remove thumbnail url and replace the original part of the Url with the new part
        photoUrl = photoUrl.substring(0, photoUrl.length() - 15) + "s400-c/photo.jpg";

    }
    else
    {
        photoUrl = user.getPhotoUrl().toString();
    }

    Picasso.with(this)
            .load(photoUrl)
            .placeholder(R.drawable.profile_avatar)
            .error(R.drawable.profile_avatar) 
            .into(circleImageView);

}
Caterinacatering answered 18/9, 2018 at 11:42 Comment(1)
just orginalString.replace(oldValue, newValue) in kotlinIndia
P
0

Instead of replacing the size, you can also just remove =s96-c from the photoUrl, and you will be receive the max size.

Paronychia answered 5/3, 2022 at 19:54 Comment(0)
C
0

you can use something like this:

urlProfile = this.auth.currentUser.photoURL?.replace('s96-c', 's400-c');
Circassia answered 1/10 at 2:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.