A Bitmoji is simply an emoji of a person’s resemblance. Users across different social media platforms commonly use them as customized emojis that attempts to replicate a user's physical appearance.
Here is an example of Bitmojis:
This post will cover generating a custom Bitmoji using a Next.js application.
APIs and Platforms for Bitmoji
One of the most common platforms for creating and customizing Bitmoji is https://www.bitmoji.com/. Other platforms are:
- Facebook Avatar
- Snapchat
- Mirror AI
- Canva Bitmoji
Prerequisites
To fully follow this tutorial, you will need the following:
- Node.js Installed
- Mirror AI Account (Mirror AI offers a free subscription for limited API calls)
- React.js/Next.js
Live Demo and GitHub
You can get the live demo at CodeSandbox, and the source code is available on GitHub.
Mirror AI API
For this post, you will use Mirror AI to generate custom Bitmoji. Mirror AI enables a user to generate Bitmojis and stickers with their face. Users upload an image with their face, and the API transforms it into a Bitmoji.
One must have an account to get the API key to use the API. Use this link to create a Free Account: https://business.mirror-ai.com/pricing. Once the account is successfully created, you will be redirected to an API dashboard page containing API keys and links to documentation.
For this post, you will use the /generate
API to upload and get a custom Bitmoji.
To test the /generate
API, click the Try it out button on the top right. Copy your API key from your account dashboard. Paste the token inside the X-Token input box:
Inside the Request body container, click the Choose File input to upload an image.
Note: For better results, use an up-close image, i.e.:
After selecting an image, click on the blue Execute button:
The API returns the following after a successful execution:
1{2 "ok": true,3 "face": {4 "id": "C7asFWrkQKC001U_8N55pg",5 "version": "yB4",6 "url": "https://f.mirror-ai.net/x/mjmTO_wGOteE7Zlvg9tuj820OaLCMZKcRBXRP7LiiO19QENeSW_1uc1VIIY4LxQJMLALuDzM7CzWD4DA6KYURIkSxNKyb6tRmhdg372x974"7 }8 }
The Bitmoji created below was obtained from the url
inside the response:
Creating a Next.js Application
To create, open the terminal and run the following:
npx create-next-app bitmoji-generator
Once the installation is complete, run the development server to confirm a successful setup:
npm run dev
For basic styling of the page, you will use bootstrap css. To install bootstrap, run the following in the terminal:
npm i bootstrap@5.2.0
Once the installation is complete, import Bootstrap inside pages/_app.js
file:
1import 'bootstrap/dist/css/bootstrap.min.css'2 import '../styles/globals.css'3 function MyApp({ Component, pageProps }) {4 return <Component {...pageProps} />5 }6 export default MyApp
Working with the API
Mirror AI is developed for use inside server-side code, but since you are using Next.js, a client-side library, you will have to use a different approach. You will need to install the following modules:
multer
: A middleware to handle file uploads of typemultipart/form-data
cors
: A Node.js middleware to handle and manage Cross-Origin Resource Sharing(CORS)form-data
: A library to be used to submit forms and file uploads to other web applications
Install the modules by running the following command:
npm install multer cors form-data
Inside the pages/api
directory, add a new file: mirror.js
, then paste the code snippet below:
1import multer from 'multer'2const axios = require('axios')3const FormData = require('form-data')4const fs = require('fs')56export const config = {7 api: {8 bodyParser: false,9 },10}1112const storage = multer.diskStorage({13 destination: './public/uploads',14 filename: (req, file, cb) => cb(null, file.originalname),15})1617const upload = multer({18 storage,19})2021export default function mirror(req, res) {22 upload.single('file')(req, {}, async (err) => {23 const filePath = `./public/uploads/${req.file.originalname}`24 const form = new FormData()25 form.append(26 'photo',27 fs.readFileSync(filePath),28 `${req.file.filename};type=${req.file.mimetype}`29 )3031 const response = await axios.post(32 'https://public-api.mirror-ai.net/v2/generate',33 form,34 {35 params: {36 style: 'kenga',37 },38 headers: {39 ...form.getHeaders(),40 accept: 'application/json',41 'X-Token': 'f63272366f3b4d56915b620101a7a2e7',42 'Content-Type': 'multipart/form-data',43 },44 }45 )4647 if (response.data.ok) {48 res.status(200).json({ msg: response.data })49 } else {50 res.status(500).json({ msg: 'error' })51 }52 })53}
In the code above, multer is used to enable file upload and specify the upload directory:
1const storage = multer.diskStorage({2 destination: './public/uploads',3 filename: (req, file, cb) => cb(null, file.originalname),4 })5 const upload = multer({6 storage,7 })
Inside the mirror()
function, you use fetch API to send data to mirror ai API:
1const response = await axios.post(2 'https://public-api.mirror-ai.net/v2/generate',3 form,4 {5 params: {6 style: 'kenga',7 },8 headers: {9 ...form.getHeaders(),10 accept: 'application/json',11 'X-Token': 'f63272366f3b4d56915b620101a7a2e7',12 'Content-Type': 'multipart/form-data',13 },14 }15 )
Once the upload is successful, you return the response:
1if (response.data.ok) {2 res.status(200).json({ msg: response.data })3 } else {4 res.status(500).json({ msg: 'error' })5 }
Form: Uploading Image
For a user to upload their image, you will use form input of type that takes in files:
<input type='file' />
Create a new directory called components
, add a new file ImageUploadForm.jsx
, and add the following snippet below:
1import Image from 'next/image'2 import { useState } from 'react'34 const ImageUploadForm = () => {5 // upload image to API6 const [image, setImage] = useState(null)7 const [imgResult, setImgResult] = useState(null)89 const handleImageUpload = (e) => {10 // get file from event11 setImage(e.target.files[0])12 }13 const handleSubmit = (e) => {14 e.preventDefault()15 const formData = new FormData()16 formData.append('file', image)17 fetch('/api/mirror', {18 method: 'POST',19 body: formData,20 })21 .then((res) => res.json())22 .then((res) => setImgResult(res.msg.face.url))23 .catch((err) => console.log(err))24 }25 return (26 <div>27 <form className='form form-control' onSubmit={handleSubmit}>28 <div className='m-4'>29 <label htmlFor='formFileLg' className='form-label'>30 Upload Your Photo31 </label>32 <input33 className='form-control form-control-lg'34 type='file'35 required36 onChange={handleImageUpload}37 />38 <button className='btn btn-primary mt-3' type='submit'>39 Submit40 </button>41 </div>42 </form>43 {imgResult && (44 <Image alt='bitmoji' width={500} height='500' src={imgResult} />45 )}46 </div>47 )48 }49 export default ImageUploadForm
In the snippet above, you’ve used React Hooks to handle image uploads and get the new image from the API:
1const [image, setImage] = useState(null)2 const [imgResult, setImgResult] = useState(null)
You will have a handleImageUpload()
and handleSubmit()
to handle events when a user uploads an image and after the image is submited:
1const handleImageUpload = (e) => {2 // get file from event3 setImage(e.target.files[0])4 }5 const handleSubmit = (e) => {6 e.preventDefault()7 const formData = new FormData()8 formData.append('file', image)9 fetch('/api/mirror', {10 method: 'POST',11 body: formData,12 })13 .then((res) => res.json())14 .then((res) => setImgResult(res.msg.face.url))15 .catch((err) => console.log(err))16 }
Run the local server to view the changes:
npm run dev
Try uploading an image with a good view of the face and notice the changes:
Conclusion:
This post demonstrates how Mirror API generates custom Bitmoji.