{"id":22396,"date":"2021-08-04T14:37:37","date_gmt":"2021-08-04T14:37:37","guid":{"rendered":"http:\/\/overlaying_glasses_or_masks_on_avatars_with_vue_js_and_cloudinary"},"modified":"2021-08-04T14:37:37","modified_gmt":"2021-08-04T14:37:37","slug":"overlaying_glasses_or_masks_on_avatars_with_vue_js_and_cloudinary","status":"publish","type":"post","link":"https:\/\/cloudinary.com\/blog\/overlaying_glasses_or_masks_on_avatars_with_vue_js_and_cloudinary","title":{"rendered":"Overlaying Glasses Or Masks on Avatars With Vue.js and Cloudinary"},"content":{"rendered":"<div class=\"wp-block-cloudinary-markdown \"><p>Deep learning, a subset of machine learning, breaks down tasks in ways that make all kinds of machine assists possible. With deep learning, you can identify images by machine, i.e., instead of hand-coding software with specific instructions for a task, you train the machine with large amounts of data and algorithms that enable it to learn how to perform the task.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/image\/upload\/w_700,c_fill,f_auto,q_auto,dpr_2.0\/Web_Assets\/blog\/july_cld_hp.png\" alt=\"Cloudinary\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1400\" height=\"697\"\/><\/p>\n<p>Even if you have the technical expertise to train models to identify images and detect next-level facial attributes, you can now leverage cognitive services to do your bidding. It\u2019s amazing!<\/p>\n<p>This article shows you how to, with Cloudinary and Microsoft Cognitive Services, build an app that shows how <strong>users look wearing various glasses or masks, helping them decide what to purchase.<\/strong><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/image\/upload\/w_700,c_fill,f_auto,q_auto,dpr_2.0\/Web_Assets\/blog\/upload-image-for-mask.png\" alt=\"Before and after\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1400\" height=\"1026\"\/><\/p>\n<p>By way of background, Cloudinary is a media platform on which web and app developers like you can manage the media lifecycle in simple steps: upload rich media, including images and videos, to the cloud for storage; transform and optimize them with dynamic URLs; and deliver them through a multi-CDN system. In essence, do all that without leaving your application code.<\/p>\n<p>Additionally, <a href=\"https:\/\/cloudinary.com\/documentation\/cloudinary_sdks\">SDKs<\/a> are available from Cloudinary for most popular programming languages, including server side, client side, and mobile. As shown in this post, we\u2019re also applying deep learning to enhance our offering.<\/p>\n<h2>The Procedure<\/h2>\n<p>Follow the steps below.<\/p>\n<h3>Step 1: Create a Cloudinary account.<\/h3>\n<p><a href=\"https:\/\/cloudinary.com\/users\/register\/free\">Sign up<\/a> for a free Cloudinary account.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/image\/upload\/w_700,c_fill,f_auto,q_auto,dpr_2.0\/Web_Assets\/blog\/cld-signup.png\" alt=\"Sign up for Cloudinary\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1400\" height=\"913\"\/><\/p>\n<p>Afterwards, log in and you will be redirected to the dashboard on which are displayed your credentials: your cloud name, API key, and API secret. Take note of them for use later in this tutorial.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/image\/upload\/w_700,c_fill,f_auto,q_auto,dpr_2.0\/Web_Assets\/blog\/cld-dashboard-mask.png\" alt=\"Cloudinary dashboard\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1400\" height=\"716\"\/><\/p>\n<h3>Step 2: Set up a Node server.<\/h3>\n<p>Initialize a <code>package.json<\/code> file:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\"> npm init\n<\/code><\/span><\/pre>\n<p>Install the modules:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">npm install express connect-multiparty cloudinary cors body-parser --save\n<\/code><\/span><\/pre>\n<p>Here\u2019s what the modules are for:<\/p>\n<ul>\n<li>\n<code>express<\/code>: For API routes.<\/li>\n<li>\n<code>connect-multiparty<\/code>: For parsing of HTTP requests with multipart <code>content-type<\/code> or <code>form-data<\/code>.<\/li>\n<li>\n<code>cloudinary<\/code>: For using Cloudinary\u2019s Node.js SDK.<\/li>\n<li>\n<code>cors<\/code>: For enabling cross-origin resource sharing (CORS).<\/li>\n<li>\n<code>body-parser<\/code>: For attaching the request body to <code>express<\/code>\u2019s <code>req<\/code> object.<\/li>\n<\/ul>\n<h3>Step 3: Activate the add-on for advanced detection of facial attributes.<\/h3>\n<p>From your dashboard, go to the <a href=\"https:\/\/cloudinary.com\/addons\">Cloudinary Add-Ons section<\/a>. Click <a href=\"https:\/\/cloudinary.com\/addons#aws_rek_face\">Rekognition Celebrity Detection<\/a> and select the Free Plan.<\/p>\n<div class='c-callout  c-callout--inline-title c-callout--note'><strong class='c-callout__title'>Note:<\/strong> <p>You can change to another plan as your usage increases.<\/p><\/div>\n<h3>Step 4: Identify the facial attributes.<\/h3>\n<p>In your root directory, create a <code>server.js<\/code> file in which to set up <code>require<\/code> parameters for the modules you just installed, like this:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php shcb-wrap-lines\"><span class=\"hljs-keyword\">const<\/span> express = <span class=\"hljs-keyword\">require<\/span>(<span class=\"hljs-string\">'express'<\/span>);\n<span class=\"hljs-keyword\">const<\/span> app = express();\n<span class=\"hljs-keyword\">const<\/span> multipart = <span class=\"hljs-keyword\">require<\/span>(<span class=\"hljs-string\">'connect-multiparty'<\/span>);\n<span class=\"hljs-keyword\">const<\/span> cloudinary = <span class=\"hljs-keyword\">require<\/span>(<span class=\"hljs-string\">'cloudinary'<\/span>);\n<span class=\"hljs-keyword\">const<\/span> cors = <span class=\"hljs-keyword\">require<\/span>(<span class=\"hljs-string\">'cors'<\/span>);\n<span class=\"hljs-keyword\">const<\/span> bodyParser = <span class=\"hljs-keyword\">require<\/span>(<span class=\"hljs-string\">'body-parser'<\/span>);\n\napp.<span class=\"hljs-keyword\">use<\/span>(<span class=\"hljs-title\">bodyParser<\/span>.<span class=\"hljs-title\">json<\/span>());\napp.<span class=\"hljs-keyword\">use<\/span>(<span class=\"hljs-title\">bodyParser<\/span>.<span class=\"hljs-title\">urlencoded<\/span>({ <span class=\"hljs-title\">extended<\/span>: <span class=\"hljs-title\">true<\/span> }));\napp.<span class=\"hljs-keyword\">use<\/span>(<span class=\"hljs-title\">cors<\/span>());\n\n<span class=\"hljs-keyword\">const<\/span> multipartMiddleware = multipart();\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>Next, configure Cloudinary:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css shcb-wrap-lines\"><span class=\"hljs-selector-tag\">cloudinary<\/span><span class=\"hljs-selector-class\">.config<\/span>({\n    <span class=\"hljs-attribute\">cloud_name<\/span>: <span class=\"hljs-string\">'xxxxxxxx'<\/span>,\n    api_key: <span class=\"hljs-string\">'xxxxxxxx'<\/span>,\n    api_secret: <span class=\"hljs-string\">'xxxxxxx'<\/span>\n});\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>Replace the three variables <code>xxxxxx<\/code> with the values from your dashboard.<\/p>\n<p>Add the route for uploading and call it <code>\/upload<\/code>:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">app.post(<span class=\"hljs-string\">'\/upload'<\/span>, multipartMiddleware, <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span>(<span class=\"hljs-params\">req, res<\/span>) <\/span>{\n  <span class=\"hljs-comment\">\/\/ Upload to Cloudinary<\/span>\n  cloudinary.v2.uploader.upload(req.files.image.path,\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span>(<span class=\"hljs-params\">error, result<\/span>) <\/span>{\n      res.json(result);\n    },\n    <span class=\"hljs-comment\">\/\/ Specify transformation and detection of facial attributes.<\/span>\n    {\n      <span class=\"hljs-attr\">transformation<\/span>: &#91;\n        { <span class=\"hljs-attr\">width<\/span>: <span class=\"hljs-number\">700<\/span>, <span class=\"hljs-attr\">radius<\/span>: <span class=\"hljs-string\">\"max\"<\/span>, <span class=\"hljs-attr\">crop<\/span>: <span class=\"hljs-string\">\"scale\"<\/span> },\n        { <span class=\"hljs-attr\">flags<\/span>: <span class=\"hljs-string\">\"region_relative\"<\/span>, <span class=\"hljs-attr\">gravity<\/span>: <span class=\"hljs-string\">\"adv_eyes\"<\/span>, <span class=\"hljs-attr\">overlay<\/span>: req.body.item, <span class=\"hljs-attr\">width<\/span>: <span class=\"hljs-string\">\"1.7\"<\/span> }\n      ]\n    });\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>The <code>overlay<\/code> parameter takes the value of <code>req.body.item<\/code>. In this app, that value is <code>glasses<\/code> or <code>harlequinmask<\/code>.<\/p>\n<div class='c-callout  c-callout--inline-title c-callout--note'><strong class='c-callout__title'>Note:<\/strong> <p>I\u2019ve uploaded the two photos below to my Cloudinary account and renamed the top one <code>harlequinmask<\/code> and the bottom one <code>glasses<\/code>, which you\u2019ll use as overlays for this app. Upload these two images to your account.<\/p><\/div>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/image\/upload\/w_400,c_fill,f_auto,q_auto\/Web_Assets\/blog\/mask-overlay.png\" alt=\"mask\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"400\" height=\"160\"\/><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/image\/upload\/w_400,c_fill,f_auto,q_auto\/Web_Assets\/blog\/glasses-overlay.png\" alt=\"Glasses\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"400\" height=\"141\"\/><\/p>\n<p>Cloudinary\u2019s <a href=\"https:\/\/cloudinary.com\/documentation\/advanced_facial_attributes_detection_addon#:~:text=Based%20on%20the%20position%20of,or%20calling%20Cloudinary's%20image%20API.\">Advanced Facial Attribute Detection<\/a> add-on detects specific facial attributes, including the exact position of the eyes of each of the faces in a photo. Based on that information, Cloudinary can position overlays on top of all the detected eye-pairs in an image.<\/p>\n<p>To smartly overlay <code>glasses<\/code> or <code>harlequinmask<\/code> on top of the detected eye-pairs in the image uploaded by the user, I\u2019ve set the overlay parameter to the ID of the <code>harlequinmask<\/code> or <code>glasses<\/code> image, and the <code>gravity<\/code> parameter to <code>adv_eyes<\/code>. I\u2019ve also set <code>region_relative_ flag<\/code> with a 1.7 width to scale the overlay to 170 percent of the width of the detected eyes, and resized the image to an oval thumbnail with a width of 700 pixels.<\/p>\n<p>Once a user makes a <code>POST<\/code> request to the <code>\/upload<\/code> route, the route grabs the image file from the HTTP request, uploads the file to Cloudinary, identifies the pair of eyes, and overlays them with the option the user chooses ( <code>glasses<\/code> or <code>harlequinmask<\/code>), and returns the correct URL.<\/p>\n<div class='c-callout  c-callout--inline-title c-callout--note'><strong class='c-callout__title'>Note:<\/strong> <p>Cloudnary\u2019s Advanced Facial Attribute Detection add-on is an integrated face-detection tool that uses <a href=\"https:\/\/azure.microsoft.com\/en-us\/services\/cognitive-services\/face\/\">Microsoft Cognitive Services<\/a> to detect the location of high-precision faces with state-of-the-art, cloud-based algorithms that can recognize up to 64 human faces in an image. Afterwards, the add-on returns the detected faces with rectangles (left, top, width, and height) to pinpoint the location of the faces in the image in pixels, the exact position of the eyes, mouth, eyebrows, nose, and lips, as well as other related attributes, such as pose, gender, and age, from each of the faces.<\/p><\/div>\n<p>Finally, test the face-detection capability with <a href=\"https:\/\/www.postman.com\/\">Postman<\/a>.<\/p>\n<h3>Step 5: Build the front end.<\/h3>\n<p>Flesh out the front end with the progressive framework <a href=\"https:\/\/vuejs.org\/\">Vue.js<\/a> by following these steps:<\/p>\n<p><strong>1.<\/strong> Install the Vue command-line interface (CLI):<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\"> npm install -g vue-cli\n<\/code><\/span><\/pre>\n<p><strong>2.<\/strong> Create a simple Vue project with the Vue CLI:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">vue init simple productshowcase\n<\/code><\/span><\/pre>\n<p><strong>3.<\/strong> Go to the <code>productshowcase<\/code> directory and create an <code>index.html<\/code> file with the following code:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-wrap-lines\"><span class=\"hljs-meta\">&lt;!DOCTYPE <span class=\"hljs-meta-keyword\">html<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">html<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">head<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">title<\/span>&gt;<\/span>Welcome to Vue<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">title<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">script<\/span> <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">\"https:\/\/unpkg.com\/vue\"<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">script<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">script<\/span> <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">\"https:\/\/unpkg.com\/axios\/dist\/axios.min.js\"<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">script<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">link<\/span> <span class=\"hljs-attr\">rel<\/span>=<span class=\"hljs-string\">\"stylesheet\"<\/span> <span class=\"hljs-attr\">href<\/span>=<span class=\"hljs-string\">\"https:\/\/maxcdn.bootstrapcdn.com\/bootstrap\/3.3.7\/css\/bootstrap.min.css\"<\/span> <span class=\"hljs-attr\">integrity<\/span>=<span class=\"hljs-string\">\"sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz\/K68vbdEjh4u\"<\/span> <span class=\"hljs-attr\">crossorigin<\/span>=<span class=\"hljs-string\">\"anonymous\"<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">head<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">body<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">id<\/span>=<span class=\"hljs-string\">\"app\"<\/span>&gt;<\/span>\n\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"container\"<\/span> <span class=\"hljs-attr\">style<\/span>=<span class=\"hljs-string\">\"margin-top: 3%; margin-left: 2%;\"<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"col-md-6\"<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"col-md-6\"<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">img<\/span> <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">\"https:\/\/res.cloudinary.com\/unicodeveloper\/image\/upload\/v1505797868\/glasses.png\"<\/span> <span class=\"hljs-attr\">width<\/span>=<span class=\"hljs-string\">\"200\"<\/span> <span class=\"hljs-attr\">height<\/span>=<span class=\"hljs-string\">\"100\"<\/span> \/&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">span<\/span>&gt;<\/span> Glasses <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">span<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"col-md-6\"<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">img<\/span> <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">\"https:\/\/res.cloudinary.com\/unicodeveloper\/image\/upload\/v1505794374\/oie_transparent.png\"<\/span> <span class=\"hljs-attr\">width<\/span>=<span class=\"hljs-string\">\"200\"<\/span> <span class=\"hljs-attr\">height<\/span>=<span class=\"hljs-string\">\"100\"<\/span> \/&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">span<\/span>&gt;<\/span> Harlequin Mask <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">span<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">hr<\/span> \/&gt;<\/span>\n\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">form<\/span> <span class=\"hljs-attr\">enctype<\/span>=<span class=\"hljs-string\">\"multipart\/form-data\"<\/span> @<span class=\"hljs-attr\">submit.prevent<\/span>=<span class=\"hljs-string\">\"onSubmit\"<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"form-group\"<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">select<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"form-control\"<\/span> <span class=\"hljs-attr\">name<\/span>=<span class=\"hljs-string\">\"item\"<\/span> <span class=\"hljs-attr\">v-model<\/span>=<span class=\"hljs-string\">\"model.item\"<\/span>&gt;<\/span>\n              <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">option<\/span> <span class=\"hljs-attr\">disabled<\/span> <span class=\"hljs-attr\">value<\/span>=<span class=\"hljs-string\">\"\"<\/span>&gt;<\/span>Choose an item<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">option<\/span>&gt;<\/span>\n              <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">option<\/span> <span class=\"hljs-attr\">value<\/span>=<span class=\"hljs-string\">\"glasses\"<\/span>&gt;<\/span> Glasses <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">option<\/span>&gt;<\/span>\n              <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">option<\/span> <span class=\"hljs-attr\">value<\/span>=<span class=\"hljs-string\">\"harlequinmask\"<\/span>&gt;<\/span> Harlequin Mask <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">option<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">select<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"form-group\"<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">label<\/span> <span class=\"hljs-attr\">for<\/span>=<span class=\"hljs-string\">\"\"<\/span>&gt;<\/span>File:<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">label<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">input<\/span> <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">\"file\"<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"form-control\"<\/span> <span class=\"hljs-attr\">accept<\/span>=<span class=\"hljs-string\">\"image\/*\"<\/span> <span class=\"hljs-attr\">name<\/span>=<span class=\"hljs-string\">\"image\"<\/span> <span class=\"hljs-attr\">v-on:change<\/span>=<span class=\"hljs-string\">\"upload($event.target.files)\"<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"form-group\"<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"btn btn-primary\"<\/span> &gt;<\/span>Upload<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">button<\/span>&gt;<\/span>\n            {{ loading }}\n          <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">form<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"col-md-4\"<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"col-md-6\"<\/span> <span class=\"hljs-attr\">style<\/span>=<span class=\"hljs-string\">\"margin-top: 20%;\"<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">img<\/span> <span class=\"hljs-attr\">id<\/span>=<span class=\"hljs-string\">\"originalface\"<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"img-responsive\"<\/span> <span class=\"hljs-attr\">alt<\/span>=<span class=\"hljs-string\">\"\"<\/span> <span class=\"hljs-attr\">width<\/span>=<span class=\"hljs-string\">\"600\"<\/span> <span class=\"hljs-attr\">height<\/span>=<span class=\"hljs-string\">\"600\"<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"col-md-6\"<\/span> <span class=\"hljs-attr\">style<\/span>=<span class=\"hljs-string\">\"margin-top: 20%;\"<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">img<\/span> <span class=\"hljs-attr\">:src<\/span>=<span class=\"hljs-string\">\"maskedface\"<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"img-responsive\"<\/span> <span class=\"hljs-attr\">alt<\/span>=<span class=\"hljs-string\">\"\"<\/span> <span class=\"hljs-attr\">width<\/span>=<span class=\"hljs-string\">\"400\"<\/span> <span class=\"hljs-attr\">height<\/span>=<span class=\"hljs-string\">\"400\"<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">script<\/span>&gt;<\/span><span class=\"javascript\">\n    <span class=\"hljs-keyword\">new<\/span> Vue({\n      <span class=\"hljs-attr\">el<\/span>: <span class=\"hljs-string\">'#app'<\/span>,\n      <span class=\"hljs-attr\">data<\/span>: <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n        <span class=\"hljs-keyword\">return<\/span> {\n          <span class=\"hljs-attr\">model<\/span>: {\n           <span class=\"hljs-attr\">text<\/span>: <span class=\"hljs-string\">''<\/span>,\n           <span class=\"hljs-attr\">image<\/span>: <span class=\"hljs-literal\">null<\/span>,\n           <span class=\"hljs-attr\">item<\/span>: <span class=\"hljs-string\">''<\/span>\n          },\n          <span class=\"hljs-attr\">maskedface<\/span>: <span class=\"hljs-literal\">null<\/span>,\n          <span class=\"hljs-attr\">loading<\/span>: <span class=\"hljs-string\">''<\/span>,\n        }\n      },\n      <span class=\"hljs-attr\">methods<\/span>: {\n        <span class=\"hljs-attr\">upload<\/span>: <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span>(<span class=\"hljs-params\">files<\/span>) <\/span>{\n          <span class=\"hljs-keyword\">this<\/span>.model.image = files&#91;<span class=\"hljs-number\">0<\/span>]\n          <span class=\"hljs-keyword\">this<\/span>.showPreview(files&#91;<span class=\"hljs-number\">0<\/span>]);\n        },\n        <span class=\"hljs-attr\">showPreview<\/span>: <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span>(<span class=\"hljs-params\">file<\/span>) <\/span>{\n          <span class=\"hljs-keyword\">var<\/span> reader = <span class=\"hljs-keyword\">new<\/span> FileReader();\n          reader.onload = <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> (<span class=\"hljs-params\">e<\/span>) <\/span>{\n              <span class=\"hljs-built_in\">document<\/span>.getElementById(<span class=\"hljs-string\">\"originalface\"<\/span>).src = e.target.result;\n          };\n          <span class=\"hljs-comment\">\/\/ read the image file as a data URL.<\/span>\n          reader.readAsDataURL(file);\n        },\n        <span class=\"hljs-attr\">onSubmit<\/span>: <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n          <span class=\"hljs-comment\">\/\/ Assemble form data<\/span>\n          <span class=\"hljs-keyword\">const<\/span> formData = <span class=\"hljs-keyword\">new<\/span> FormData()\n          formData.append(<span class=\"hljs-string\">'image'<\/span>, <span class=\"hljs-keyword\">this<\/span>.model.image);\n          formData.append(<span class=\"hljs-string\">'item'<\/span>, <span class=\"hljs-keyword\">this<\/span>.model.item);\n          <span class=\"hljs-keyword\">this<\/span>.loading = <span class=\"hljs-string\">\"Processing....Please be patient.\"<\/span>\n\n          <span class=\"hljs-comment\">\/\/ Post to server<\/span>\n          axios.post(<span class=\"hljs-string\">'https:\/\/localhost:3333\/upload'<\/span>, formData)\n          .then(<span class=\"hljs-function\"><span class=\"hljs-params\">res<\/span> =&gt;<\/span> {\n            <span class=\"hljs-comment\">\/\/ Update UI<\/span>\n            <span class=\"hljs-keyword\">this<\/span>.maskedface = res.data.url\n            <span class=\"hljs-keyword\">this<\/span>.loading = <span class=\"hljs-string\">''<\/span>\n          })\n        }\n      }\n    })\n  <\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">script<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">body<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">html<\/span>&gt;<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p><strong>4.<\/strong> Run the app.<\/p>\n<p>Let\u2019s step through the code. First, take a look at the form for uploading images.<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-wrap-lines\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">form<\/span> <span class=\"hljs-attr\">enctype<\/span>=<span class=\"hljs-string\">\"multipart\/form-data\"<\/span> @<span class=\"hljs-attr\">submit.prevent<\/span>=<span class=\"hljs-string\">\"onSubmit\"<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"form-group\"<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">select<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"form-control\"<\/span> <span class=\"hljs-attr\">name<\/span>=<span class=\"hljs-string\">\"item\"<\/span> <span class=\"hljs-attr\">v-model<\/span>=<span class=\"hljs-string\">\"model.item\"<\/span>&gt;<\/span>\n              <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">option<\/span> <span class=\"hljs-attr\">disabled<\/span> <span class=\"hljs-attr\">value<\/span>=<span class=\"hljs-string\">\"\"<\/span>&gt;<\/span>Choose an item<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">option<\/span>&gt;<\/span>\n              <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">option<\/span> <span class=\"hljs-attr\">value<\/span>=<span class=\"hljs-string\">\"glasses\"<\/span>&gt;<\/span> Glasses <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">option<\/span>&gt;<\/span>\n              <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">option<\/span> <span class=\"hljs-attr\">value<\/span>=<span class=\"hljs-string\">\"harlequinmask\"<\/span>&gt;<\/span> Harlequin Mask <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">option<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">select<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"form-group\"<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">label<\/span> <span class=\"hljs-attr\">for<\/span>=<span class=\"hljs-string\">\"\"<\/span>&gt;<\/span>File:<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">label<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">input<\/span> <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">\"file\"<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"form-control\"<\/span> <span class=\"hljs-attr\">accept<\/span>=<span class=\"hljs-string\">\"image\/*\"<\/span> <span class=\"hljs-attr\">name<\/span>=<span class=\"hljs-string\">\"image\"<\/span> <span class=\"hljs-attr\">v-on:change<\/span>=<span class=\"hljs-string\">\"upload($event.target.files)\"<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"form-group\"<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"btn btn-primary\"<\/span> &gt;<\/span>Upload<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">button<\/span>&gt;<\/span>\n            {{ loading }}\n          <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n   <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">form<\/span>&gt;<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>Note that you\u2019ve bound the upload form to an upload event-handler and attached a change event to the <strong>Choose File<\/strong> button. Once a user has picked a file, the <code>showPreview<\/code> method called in the Vue instance below is invoked, showing a thumbnail preview of the image about to be uploaded.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/image\/upload\/w_700,c_fill,f_auto,q_auto\/Web_Assets\/blog\/upload-mask-demo.png\" alt=\"Thumbnail preview of the image about to be uploaded\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"700\" height=\"513\"\/>\n<em>Thumbnail preview of the image about to be uploaded<\/em><\/p>\n<p>Check out the methods, model, and data properties on your Vue instance:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-keyword\">new<\/span> Vue({\n      <span class=\"hljs-attr\">el<\/span>: <span class=\"hljs-string\">'#app'<\/span>,\n      <span class=\"hljs-attr\">data<\/span>: <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n        <span class=\"hljs-keyword\">return<\/span> {\n          <span class=\"hljs-attr\">model<\/span>: {\n           <span class=\"hljs-attr\">text<\/span>: <span class=\"hljs-string\">''<\/span>,\n           <span class=\"hljs-attr\">image<\/span>: <span class=\"hljs-literal\">null<\/span>,\n           <span class=\"hljs-attr\">item<\/span>: <span class=\"hljs-string\">''<\/span>\n          },\n          <span class=\"hljs-attr\">maskedface<\/span>: <span class=\"hljs-literal\">null<\/span>,\n          <span class=\"hljs-attr\">loading<\/span>: <span class=\"hljs-string\">''<\/span>,\n        }\n      },\n      <span class=\"hljs-attr\">methods<\/span>: {\n        <span class=\"hljs-attr\">upload<\/span>: <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span>(<span class=\"hljs-params\">files<\/span>) <\/span>{\n          <span class=\"hljs-keyword\">this<\/span>.model.image = files&#91;<span class=\"hljs-number\">0<\/span>]\n          <span class=\"hljs-keyword\">this<\/span>.showPreview(files&#91;<span class=\"hljs-number\">0<\/span>]);\n        },\n        <span class=\"hljs-attr\">showPreview<\/span>: <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span>(<span class=\"hljs-params\">file<\/span>) <\/span>{\n          <span class=\"hljs-keyword\">var<\/span> reader = <span class=\"hljs-keyword\">new<\/span> FileReader();\n          reader.onload = <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> (<span class=\"hljs-params\">e<\/span>) <\/span>{\n              <span class=\"hljs-built_in\">document<\/span>.getElementById(<span class=\"hljs-string\">\"originalface\"<\/span>).src = e.target.result;\n          };\n          <span class=\"hljs-comment\">\/\/ read the image file as a data URL.<\/span>\n          reader.readAsDataURL(file);\n        },\n        <span class=\"hljs-attr\">onSubmit<\/span>: <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n          <span class=\"hljs-comment\">\/\/ Assemble form data<\/span>\n          <span class=\"hljs-keyword\">const<\/span> formData = <span class=\"hljs-keyword\">new<\/span> FormData()\n          formData.append(<span class=\"hljs-string\">'image'<\/span>, <span class=\"hljs-keyword\">this<\/span>.model.image);\n          formData.append(<span class=\"hljs-string\">'item'<\/span>, <span class=\"hljs-keyword\">this<\/span>.model.item);\n          <span class=\"hljs-keyword\">this<\/span>.loading = <span class=\"hljs-string\">\"Processing....Please be patient.\"<\/span>\n\n          <span class=\"hljs-comment\">\/\/ Post to server<\/span>\n          axios.post(<span class=\"hljs-string\">'https:\/\/localhost:3333\/upload'<\/span>, formData)\n          .then(<span class=\"hljs-function\"><span class=\"hljs-params\">res<\/span> =&gt;<\/span> {\n            <span class=\"hljs-comment\">\/\/ Update UI<\/span>\n            <span class=\"hljs-keyword\">this<\/span>.maskedface = res.data.url\n            <span class=\"hljs-keyword\">this<\/span>.loading = <span class=\"hljs-string\">''<\/span>\n          })\n        }\n      }\n    })\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>On submission, the form calls the <code>onSubmit<\/code> function in the Vue method to make a <code>POST<\/code> request to the back end and then return the data to the front end.<\/p>\n<p>The data returned is the modified image with the overlay, which is reflected in the UI.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/image\/upload\/w_700,c_fill,f_auto,q_auto,dpr_2.0\/Web_Assets\/blog\/upload-image-for-mask.png\" alt=\"An uploaded image of Rihanna wearing the selected Harlequin mask\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1400\" height=\"1026\"\/>\n<em>An uploaded image of Rihanna wearing the selected Harlequin mask<\/em><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/image\/upload\/w_700,c_fill,f_auto,q_auto,dpr_2.0\/Web_Assets\/blog\/chris-in-mask.png\" alt=\"An uploaded Image of Christian Nwamba, aka codebeast, wearing the selected glasses\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1400\" height=\"1026\"\/>\n<em>An uploaded Image of Christian Nwamba, aka codebeast, wearing the selected glasses<\/em><\/p>\n<p>Feel free to check out the <a href=\"https:\/\/github.com\/unicodeveloper\/face-detection\">source code<\/a>.<\/p>\n<h2>Conclusion<\/h2>\n<p>You\u2019ve now learned how to use Cloudinary capabilities to detect facial attributes in an image and transform it with an overlay. The transformation options are virtually limitless. So, let your creative juices flow and enhance your business with products that users will love. As shown in this tutorial, you don\u2019t have to spend time building them: <a href=\"https:\/\/cloudinary.com\/users\/register\/free\">Cloudinary\u2019s got you!<\/a><\/p>\n<\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":41,"featured_media":22397,"comment_status":"","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_cloudinary_featured_overwrite":false,"footnotes":""},"categories":[1],"tags":[25,165,263,315],"class_list":["post-22396","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-asset-management","tag-image-transformation","tag-sdk","tag-vue"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.6 (Yoast SEO v26.9) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Overlaying Glasses Or Masks on Avatars With Vue.js and Cloudinary<\/title>\n<meta name=\"description\" content=\"How to build an app with Cloudinary and Microsoft Cognitive Services that shows how users look wearing glasses or masks.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/cloudinary.com\/blog\/overlaying_glasses_or_masks_on_avatars_with_vue_js_and_cloudinary\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Overlaying Glasses Or Masks on Avatars With Vue.js and Cloudinary\" \/>\n<meta property=\"og:description\" content=\"How to build an app with Cloudinary and Microsoft Cognitive Services that shows how users look wearing glasses or masks.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/cloudinary.com\/blog\/overlaying_glasses_or_masks_on_avatars_with_vue_js_and_cloudinary\" \/>\n<meta property=\"og:site_name\" content=\"Cloudinary Blog\" \/>\n<meta property=\"article:published_time\" content=\"2021-08-04T14:37:37+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649725962\/Web_Assets\/blog\/GlsMskOvrly_VueJS_223970644e\/GlsMskOvrly_VueJS_223970644e.png?_i=AA\" \/>\n\t<meta property=\"og:image:width\" content=\"1540\" \/>\n\t<meta property=\"og:image:height\" content=\"847\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"NewsArticle\",\"@id\":\"https:\/\/cloudinary.com\/blog\/overlaying_glasses_or_masks_on_avatars_with_vue_js_and_cloudinary#article\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/overlaying_glasses_or_masks_on_avatars_with_vue_js_and_cloudinary\"},\"author\":{\"name\":\"\",\"@id\":\"\"},\"headline\":\"Overlaying Glasses Or Masks on Avatars With Vue.js and Cloudinary\",\"datePublished\":\"2021-08-04T14:37:37+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/overlaying_glasses_or_masks_on_avatars_with_vue_js_and_cloudinary\"},\"wordCount\":11,\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/overlaying_glasses_or_masks_on_avatars_with_vue_js_and_cloudinary#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649725962\/Web_Assets\/blog\/GlsMskOvrly_VueJS_223970644e\/GlsMskOvrly_VueJS_223970644e.png?_i=AA\",\"keywords\":[\"Asset Management\",\"Image Transformation\",\"SDK\",\"Vue\"],\"inLanguage\":\"en-US\",\"copyrightYear\":\"2021\",\"copyrightHolder\":{\"@id\":\"https:\/\/cloudinary.com\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/cloudinary.com\/blog\/overlaying_glasses_or_masks_on_avatars_with_vue_js_and_cloudinary\",\"url\":\"https:\/\/cloudinary.com\/blog\/overlaying_glasses_or_masks_on_avatars_with_vue_js_and_cloudinary\",\"name\":\"Overlaying Glasses Or Masks on Avatars With Vue.js and Cloudinary\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/overlaying_glasses_or_masks_on_avatars_with_vue_js_and_cloudinary#primaryimage\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/overlaying_glasses_or_masks_on_avatars_with_vue_js_and_cloudinary#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649725962\/Web_Assets\/blog\/GlsMskOvrly_VueJS_223970644e\/GlsMskOvrly_VueJS_223970644e.png?_i=AA\",\"datePublished\":\"2021-08-04T14:37:37+00:00\",\"description\":\"How to build an app with Cloudinary and Microsoft Cognitive Services that shows how users look wearing glasses or masks.\",\"breadcrumb\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/overlaying_glasses_or_masks_on_avatars_with_vue_js_and_cloudinary#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/cloudinary.com\/blog\/overlaying_glasses_or_masks_on_avatars_with_vue_js_and_cloudinary\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/overlaying_glasses_or_masks_on_avatars_with_vue_js_and_cloudinary#primaryimage\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649725962\/Web_Assets\/blog\/GlsMskOvrly_VueJS_223970644e\/GlsMskOvrly_VueJS_223970644e.png?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649725962\/Web_Assets\/blog\/GlsMskOvrly_VueJS_223970644e\/GlsMskOvrly_VueJS_223970644e.png?_i=AA\",\"width\":1540,\"height\":847},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/cloudinary.com\/blog\/overlaying_glasses_or_masks_on_avatars_with_vue_js_and_cloudinary#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/cloudinary.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Overlaying Glasses Or Masks on Avatars With Vue.js and Cloudinary\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\",\"url\":\"https:\/\/cloudinary.com\/blog\/\",\"name\":\"Cloudinary Blog\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/cloudinary.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\",\"name\":\"Cloudinary Blog\",\"url\":\"https:\/\/cloudinary.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA\",\"width\":312,\"height\":60,\"caption\":\"Cloudinary Blog\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Overlaying Glasses Or Masks on Avatars With Vue.js and Cloudinary","description":"How to build an app with Cloudinary and Microsoft Cognitive Services that shows how users look wearing glasses or masks.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/cloudinary.com\/blog\/overlaying_glasses_or_masks_on_avatars_with_vue_js_and_cloudinary","og_locale":"en_US","og_type":"article","og_title":"Overlaying Glasses Or Masks on Avatars With Vue.js and Cloudinary","og_description":"How to build an app with Cloudinary and Microsoft Cognitive Services that shows how users look wearing glasses or masks.","og_url":"https:\/\/cloudinary.com\/blog\/overlaying_glasses_or_masks_on_avatars_with_vue_js_and_cloudinary","og_site_name":"Cloudinary Blog","article_published_time":"2021-08-04T14:37:37+00:00","og_image":[{"width":1540,"height":847,"url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649725962\/Web_Assets\/blog\/GlsMskOvrly_VueJS_223970644e\/GlsMskOvrly_VueJS_223970644e.png?_i=AA","type":"image\/png"}],"twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"NewsArticle","@id":"https:\/\/cloudinary.com\/blog\/overlaying_glasses_or_masks_on_avatars_with_vue_js_and_cloudinary#article","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/overlaying_glasses_or_masks_on_avatars_with_vue_js_and_cloudinary"},"author":{"name":"","@id":""},"headline":"Overlaying Glasses Or Masks on Avatars With Vue.js and Cloudinary","datePublished":"2021-08-04T14:37:37+00:00","mainEntityOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/overlaying_glasses_or_masks_on_avatars_with_vue_js_and_cloudinary"},"wordCount":11,"publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/overlaying_glasses_or_masks_on_avatars_with_vue_js_and_cloudinary#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649725962\/Web_Assets\/blog\/GlsMskOvrly_VueJS_223970644e\/GlsMskOvrly_VueJS_223970644e.png?_i=AA","keywords":["Asset Management","Image Transformation","SDK","Vue"],"inLanguage":"en-US","copyrightYear":"2021","copyrightHolder":{"@id":"https:\/\/cloudinary.com\/#organization"}},{"@type":"WebPage","@id":"https:\/\/cloudinary.com\/blog\/overlaying_glasses_or_masks_on_avatars_with_vue_js_and_cloudinary","url":"https:\/\/cloudinary.com\/blog\/overlaying_glasses_or_masks_on_avatars_with_vue_js_and_cloudinary","name":"Overlaying Glasses Or Masks on Avatars With Vue.js and Cloudinary","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/overlaying_glasses_or_masks_on_avatars_with_vue_js_and_cloudinary#primaryimage"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/overlaying_glasses_or_masks_on_avatars_with_vue_js_and_cloudinary#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649725962\/Web_Assets\/blog\/GlsMskOvrly_VueJS_223970644e\/GlsMskOvrly_VueJS_223970644e.png?_i=AA","datePublished":"2021-08-04T14:37:37+00:00","description":"How to build an app with Cloudinary and Microsoft Cognitive Services that shows how users look wearing glasses or masks.","breadcrumb":{"@id":"https:\/\/cloudinary.com\/blog\/overlaying_glasses_or_masks_on_avatars_with_vue_js_and_cloudinary#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/cloudinary.com\/blog\/overlaying_glasses_or_masks_on_avatars_with_vue_js_and_cloudinary"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/overlaying_glasses_or_masks_on_avatars_with_vue_js_and_cloudinary#primaryimage","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649725962\/Web_Assets\/blog\/GlsMskOvrly_VueJS_223970644e\/GlsMskOvrly_VueJS_223970644e.png?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649725962\/Web_Assets\/blog\/GlsMskOvrly_VueJS_223970644e\/GlsMskOvrly_VueJS_223970644e.png?_i=AA","width":1540,"height":847},{"@type":"BreadcrumbList","@id":"https:\/\/cloudinary.com\/blog\/overlaying_glasses_or_masks_on_avatars_with_vue_js_and_cloudinary#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/cloudinary.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Overlaying Glasses Or Masks on Avatars With Vue.js and Cloudinary"}]},{"@type":"WebSite","@id":"https:\/\/cloudinary.com\/blog\/#website","url":"https:\/\/cloudinary.com\/blog\/","name":"Cloudinary Blog","description":"","publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/cloudinary.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/cloudinary.com\/blog\/#organization","name":"Cloudinary Blog","url":"https:\/\/cloudinary.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA","width":312,"height":60,"caption":"Cloudinary Blog"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":""}]}},"jetpack_featured_media_url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649725962\/Web_Assets\/blog\/GlsMskOvrly_VueJS_223970644e\/GlsMskOvrly_VueJS_223970644e.png?_i=AA","_links":{"self":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/22396","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/users\/41"}],"replies":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/comments?post=22396"}],"version-history":[{"count":0,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/22396\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media\/22397"}],"wp:attachment":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media?parent=22396"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/categories?post=22396"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/tags?post=22396"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}