Skip to content

Nuxtjs Profile Picture Generator

Getting profile images seems like a simple task until we realize that most users just have normal solo photos of themselves. This means that they are not just headshots and the user’s face can be anywhere in the image. We thus need a smart way to obtain the headshots from user uploads. Let us learn how we can build this into our applications.

The final project can be viewed on Codesandbox.

You can find the full source code on my Github repository.

We will use Vue.Js to build this project. It defines itself as an intuitive JavaScript framework. Knowledge of Vue.Js is not required but some understanding of HTML, CSS, and JavaScript is required.

Nuxt.Js is an intuitive Vue.Js framework that allows us to build powerful and simple web applications.

To set up our project we will use the create-nuxt-app utility. To use it, make sure you have Yarn or NPM v5.2+ or v6.1+ installed. Open your terminal in your preferred working directory.


yarn create nuxt-app nuxtjs-profile-picture-generator

# OR

npx create-nuxt-app nuxtjs-profile-picture-generator

# OR

npm init nuxt-app nuxtjs-profile-picture-generator

Code language: PHP (php)

The above will trigger a set of setup questions. Here are our recommended defaults:

Project name: nuxtjs-profile-picture-generator

Programming language: JavaScript

Package manager: Yarn

UI framework: TailwindCSS

Nuxt.Js modules: N/A

Linting tools: N/A

Testing framework: None

Rendering mode: Universal (SSR/SSG)

Deployment target: Server (Node.js hosting)

Development tools: N/A

What is your Github username: <your-github-username>

Once setup is complete, feel free to enter and run the project:


cd nuxtjs-profile-picture-generator

  

yarn dev

# OR

npm run dev

Code language: PHP (php)

The application will now be running on http://localhost:3000

The platform we will use to handle our media is called Cloudinary.

We will install the recommended Nuxt.Js plugin: @nuxtjs/cloudinary. To install it, open the terminal in the project folder.


yarn add @nuxtjs/cloudinary

# OR

npm install @nuxtjs/cloudinary

Code language: CSS (css)

Once installed, add it to the modules section of our nuxt.config.js file:


// nuxt.config.js

export  default  {

....

modules: [

'@nuxtjs/cloudinary'

]

...

}

Code language: JavaScript (javascript)

We will now configure our Cloudinary instance by adding a cloudinary section in our nuxt.config.js file:


// nuxt.config.js

export  default  {

...

cloudinary: {

cloudName:  process.env.NUXT_ENV_CLOUDINARY_CLOUD_NAME,

useComponent:  true,

secure:  true

}

}

Code language: JavaScript (javascript)

Here is our first encounter with environmental variables. These are values we configure outside of our project code. This is because they are either too sensitive to be in a code repository or because they are dependent on the environment in which our code is deployed. Let us create our env file:


touch .env

Code language: CSS (css)

To obtain your Cloudinary cloud name, check the Account Details on your dashboard. If you don’t have an account, feel free to create one.

Add your cloud name to your env file


<!-- .env -->

NUXT_ENV_CLOUDINARY_CLOUD_NAME=<your-cloud-name>

Code language: HTML, XML (xml)

The first step will be enabling our app users to select and upload their full pictures. Let us create an HTML form to achieve this.


<!-- pages/index.vue -->

...

<form v-else  @submit.prevent="upload">

<input

type="file"

name="file"

@change="handleFile"

/>

<p v-if="uploading">Uploading...</p>

<button

v-else-if="image"

type="submit"

>

Convert

</button>

</form>

...

Code language: HTML, XML (xml)

When a file is selected, the handleFile method will be called to set the selected file in the current state. The upload method is responsible for taking the selected file, reading its contents, and uploading it to Cloudinary.


// pages/index.vue

<script>

export default {

data()  {

return {

uploading:  false,

image:  null,

cloudinaryImage:  null,

};

},

...

methods: {

async  handleFile(e)  {

this.image  =  e.target.files[0];

},

async  readData(f)  {

return new Promise((resolve)  =>  {

const  reader  =  new  FileReader();

reader.onloadend  =  ()  =>  resolve(reader.result);

reader.readAsDataURL(f);

});

},

async  upload()  {

this.uploading  =  true;

const imageData  =  await  this.readData(this.image);

this.cloudinaryImage  =  await  this.$cloudinary.upload(imageData,  {

upload_preset:  "default-preset",

folder:  "nuxtjs-profile-picture-generator",

});

this.uploading  =  false;

},

},

};

</script>

Code language: HTML, XML (xml)

The image file will be uploaded to the nuxtjs-profile-picture-generator folder using the default-preset upload preset. Upload presets are a set of rules we preconfigure to be applied to our uploads. To create an upload preset, proceed to the add upload preset page. Here are our recommended defaults:

Name: default-preset

Mode: unsigned

Unique filename: true

Delivery type: upload

Access mode: public

Once the file is uploaded, we store it in the cloudinaryImage variable.

To get the profile picture, we will be using Cloudinary’s inbuilt facial-detection transformations. The face gravity moves the crop cursor onto the face recognized in the image. This ensures that the face is in the center of the image. We then crop around the face. We use the thumb crop setting to ensure we get a thumbnail of the image based on the gravity setting.


// pages/index.vue

<script>

export default {

...

computed: {

imageUrl()  {

return  this.cloudinaryImage

?  this.$cloudinary.image.url(this.cloudinaryImage.public_id,  {

gravity:  "faces",

height:  200,

width:  200,

crop:  "thumb",

})

:  "https://via.placeholder.com/200";

},

},

...

};

</script>

Code language: HTML, XML (xml)

We can now render the image for the app user to view the result. On top of this, let us add a download button to download the image.


<!-- pages/index.vue -->

<template>

...

<img :src="imageUrl"  />

...

<a

v-if="cloudinaryImage"

target="_blank"

:href="imageUrl"

>

Download

</a>

...

</template>

Code language: HTML, XML (xml)

With the above application, we can dynamically get quality profile pictures from our user’s uploads. Read more on Cloudinay’s face-detection based transformations to understand other ways we can apply these wonderful algorithms in our applications.

Back to top

Featured Post