Cloudinary Blog

How to Build an Enhanced Gravatar Service, Part 2

How to Build an Enhanced Gravatar Service, Part 2

Part 1 of this post defines the capabilities of an enhanced Gravatar service, which I named Clavatar, and describes the following initial steps for building it:

  1. Set up the database.
  2. Establish the user-registration process.
  3. Install the Cloudinary PHP Library, version 2.0.0-Beta.
  4. Implement the image-upload operation.
  5. Associate images with user accounts.

This post, part 2 of the series, explains how to make Clavatar work like Gravatar and to develop Clavatar’s capabilities of enabling requests for various versions of the images related to user accounts.


Sign up for Cloudinary free today!


Image Retrieval Through User Hashes

Recall that Gravatar retrieves user images through their hash in a URL, as in this example:

https://www.gravatar.com/avatar/205e460b479e2e5b48aec07710c08d50

To enable Clavatar to do the same, set up the API endpoint, as follows:

1. Add the following to the routes/web.php file:

Copy to clipboard
$router->get('avatar/{hash}', 'AvatarController@retrieveAvatar');

2. Add the following retrieveAvatar function to the app/Http/Controllers/AvatarController.php file:

Copy to clipboard
public function retrieveAvatar(Request $request, $hash)
    {
        $defaultImageTag = $this->cloudinary->imageTag('default')->serialize();
        $defaultImageUrl = $this->cloudinary->image('default')->toUrl();

        $user = User::where('hash', $hash)->first();

        if(is_null($user)) {
            return $defaultImageTag;
        }

        $publicId = $user->avatar_id;

        $imageUrl = $this->cloudinary->image($publicId);
        $imageTag = $this->cloudinary->imageTag($publicId);

        return $imageTag->serialize();
    }

The code above does the following:

  • $this->cloudinary->imageTag('default')->serialize(); returns an <image> tag that displays an image with the public ID (public_id) default.
  • $this->cloudinary->image('default')->toUrl(); returns a link to the default image.
  • User::where('hash', $hash)->first(); checks if this hash is in the database and, if so, returns the image associated with the user account. Otherwise, the code returns the default image.

Note
A default image is already in the database. Be sure to upload another default image to your Cloudinary account’s Media Library and name it default.

3. Verify that everything works by running the API endpoint in a browser:

  • With a random hash, e.g.:

    avatar

  • With a valid hash, e.g.:

    Prosper Avatar

Now Clavatar works exactly like Gravatar.

Implementation of Other Features

Feature: Enablement of the ability to request for an image of any size by adding the size parameter, e.g., s=400 or size=400, to the URL.

Implementation Step: Update the retrieveAvatar function, as follows:

Copy to clipboard
public function retrieveAvatar(Request $request, $hash)
    {
        $defaultImageTag = $this->cloudinary->imageTag('default')->serialize();
        $defaultImageUrl = $this->cloudinary->image('default')->toUrl();

        $user = User::where('hash', $hash)->first();

        if(is_null($user)) {
            return $defaultImageTag;
        }

        $publicId = $user->avatar_id;

        $imageUrl = $this->cloudinary->image($publicId);
        $imageTag = $this->cloudinary->imageTag($publicId);

        if($request->has('s') || $request->has('size')) {
            $size = $request->query('s') ?: $request->query('size');

            $imageUrl->resize(Resize::fill($size, $size));
            $imageTag->resize(Resize::fill($size, $size));
        } else {
            $imageUrl->resize(Resize::fill(100,100));
            $imageTag->resize(Resize::fill(100,100));
        }

        return $imageTag->serialize();
    }

Result (Example):

Avatar results

Feature: Enablement of the ability to return a cartoonized version of an image by adding the d=cp parameter to the URL.

Implementation Step: Add the following to the retrieveAvatar function:

Copy to clipboard
public function retrieveAvatar(Request $request, $hash)
    {
        ….
        ….
        if($request->has('d')) {
            $defaultOption = $request->query('d');

            if($defaultOption == 'cp') {
                $imageUrl->effect(Effect::cartoonify());
                $imageTag->effect(Effect::cartoonify());
            }
        }

        return $imageTag->serialize();
    }

Result (Example):

Avatar

Feature: Enablement of the ability to request for the black-and white version of an image by adding the d=bw parameter to the URL.

Implementation Step: Update the retrieveAvatar function, as follows:

Copy to clipboard
public function retrieveAvatar(Request $request, $hash)
    {
        ….
        ….
        if($request->has('d')) {
            $defaultOption = $request->query('d');

            if($defaultOption == 'cp') {
                $imageUrl->effect(Effect::cartoonify());
                $imageTag->effect(Effect::cartoonify());
            }

           if($defaultOption == 'bw') {
                $imageUrl->effect(Effect::blackWhite(30));
                $imageTag->effect(Effect::blackWhite(30));
            }

        }

        return $imageTag->serialize();
    }

Result (Example):

BW Avatar

Feature: Enablement of the ability to request for an artistic version of an image by adding the d=hk parameter to the URL.

Implementation Step: Update the retrieveAvatar function, as follows:

Copy to clipboard
public function retrieveAvatar(Request $request, $hash)
    {
        ….
        ….
        if($request->has('d')) {
            $defaultOption = $request->query('d');

            if($defaultOption == 'cp') {
                $imageUrl->effect(Effect::cartoonify());
                $imageTag->effect(Effect::cartoonify());
            }

           if($defaultOption == 'bw') {
                $imageUrl->effect(Effect::blackWhite(30));
                $imageTag->effect(Effect::blackWhite(30));
            }

           if($defaultOption == 'hk') {
                $imageUrl->effect(Effect::artisticFilter(ArtisticFilter::HOKUSAI));
                $imageTag->effect(Effect::artisticFilter(ArtisticFilter::HOKUSAI));
            }
        }

        return $imageTag->serialize();
    }

Result (Example):

Avatar hk

Feature: Enablement of the ability to request for the compressed and optimized version of an image by adding the q=auto parameter to the URL.

Implementation Step: Add the following to the retrieveAvatar function:

Copy to clipboard
public function retrieveAvatar(Request $request, $hash)
    {
        ….
        ….
        ….
        ….
        if($request->has('q')) {
            $qualityOption = $request->query('q');

            if($qualityOption == 'auto') {
                $imageUrl->quality(Quality::auto());
                $imageTag->quality(Quality::auto());
            }
        }

        return $imageTag->serialize();
    }

Result (Example):

Avatar Quality

Feature: Enablement of the capability to request for the best format of an image by adding the f=auto parameter to the URL. This version ensures the most suitable format for whichever browser is delivering the image.

Implementation Step: Add the following to the retrieveAvatar function:

Copy to clipboard
public function retrieveAvatar(Request $request, $hash)
    {
        ….
        ….
        ….
        ….
        if($request->has('f')) {
            $formatOption = $request->query('f');

            if($formatOption == 'auto') {
                $imageUrl->format(Format::auto());
                $imageTag->format(Format::auto());
            }
        }

        return $imageTag->serialize();
    }

Result (Example):

Avatar Format

Feature: Enablement of the ability to request for the rounded-corners version of an image by adding the a rc=y parameter to the URL.

Implementation Step: Add the following to the retrieveAvatar function:

Copy to clipboard
public function retrieveAvatar(Request $request, $hash)
    {
        ….
        ….
        ….
        ….
        if($request->has('rc')) {
            $roundedOption = $request->query('rc');

            if($roundedOption == 'y') {
                $imageUrl->roundCorners(RoundCorners::max());
                $imageTag->roundCorners(RoundCorners::max());
            }
        }

        return $imageTag->serialize();
    }

Result (Example):

Rounded corners

Feature: Enablement of the ability to rotate an image by adding the r=<angle> parameter, e.g., r=40, to the URL. The value of the angle must be between 1 and 100.

Implementation Step: Add the following to the retrieveAvatar function:

Copy to clipboard
public function retrieveAvatar(Request $request, $hash)
    {
        ….
        ….
        ….
        ….
        if($request->has('r')) {
            $roundedOption = $request->query('r');

            $imageUrl->rotate($roundedOption);
            $imageTag->rotate($roundedOption);
        }

        return $imageTag->serialize();
    }

Result (Example):

Rotate

Feature: Enablement of the ability to request for a color-bordered version of an image by adding the b=<color> parameter, e.g., b=red, to the URL.

Implementation Step: Add the following to the retrieveAvatar function:

Copy to clipboard
public function retrieveAvatar(Request $request, $hash)
    {
        ….
        ….
        ….
        ….
        if($request->has('b')) {
            $borderOption = $request->query('b');

            $imageUrl->border(Border::solid()->width(3)->color($borderOption));
            $imageTag->border(Border::solid()->width(3)->color($borderOption));
        }

        return $imageTag->serialize();
    }

Result:

Outline

Combination of Parameters

You can combine as many parameters as you desire—in any order—to retrieve the image associated with an account.

Example:

To retrieve a cartoonized, circular avatar of a 500x500 size, optimized and in the best format, add the related parameters to the URL:

http://localhost:8000/avatar/7b71271e3c93106dbc3b68fb867344e9?s=500&d=hk&rc=y&f=auto&q=auto

Cloudinary returns this image:

avatar format and quality

Feel free to clone the Clavatar repository on GitHub and run the helpful service.

More Cloudinary Features

With Cloudinary, you can automate your entire image-management lifecycle, from upload and transformation to optimization and delivery. Notably, Cloudinary’s upload widget offers a superfast way to upload multiple images in bulk. The platform also features numerous capabilities for editing and managing videos.

Do check them out.

Recent Blog Posts

Partner news: Cloudinary-Getty Images Integration

Supported by intelligent automation, Cloudinary serves as an effective conduit between media asset management and delivery so you can take maximum advantage of assets, compress workflows, and build and coordinate engaging and inspiring customer experiences. Through Cloudinary’s Digital Asset Management (DAM) solution, which employs the company’s innovative image and video APIs, creative and marketing teams can benefit from them, as well as from many AI-powered and automated capabilities. As a result, you can transform, optimize, and deliver media at scale on an intuitive UI.

Read more
Why Audio in Video Matters

Many content creators and consumers tend to regard video as visuals, but that’s only part of the experience. Immersive video content includes strong audio. Just like in a movie, the audio for video content comprises many components: the narrator or subjects, the background music that sets the mood and draws viewers in, sound effects, and so forth.

Read more

For Developers: the HTML <picture> Element Explained

By Amarachi Amaechi
For Developers: the HTML <picture> Element Explained

We all know the good ol', tireless <img> element, which has been a long-time go-to for inserting graphics into webpages. Time doesn’t stop, however, and neither do technological advancements. So, let’s get you up to speed with the element’s modern alternative: the <picture> element.

Read more