_With the development of AI technology, face recognition can recognize the position and size of human facial features, and even track the movement of face in real time. As a result, the front-end has a lot of funny functions, such as face cartoon, burst and jitter. Let's see the effect of burst.
How does this work?Let's analyze it in the left image
This effect is divided into two parts
1: Background
2: Cartoon face
The cartoon face is composed of the following parts
1: Original Character Picture
2: Material pictures, such as special effect ear pictures, special effect nose pictures, special effect mouth pictures, etc.
So in order to achieve this effect, we can overlay the background, people's avatars and special effects one by one in a similar way as picture overlay.
But how do we determine the overlay position of a picture material?AI will be on the stage now, following the steps
Step 1: First the user takes a photo or uploads a photo of himself
Step 2: AI performs face recognition on photos to identify basic features, such as the size of eyes and nose
Step 3: The front end overlays each cartoon material according to AI calculation, just like the layer inside photoshop
For Step 2, the face data returned from the server should contain at least one
1) Width, Height, used to size elements
2) Left margin and upper margin to set element position
So the front-end core code is as follows
layers: [ {name:'hair', link:'xxxxxx', width: '160', height: '160' , top: '0', left: '0'}, {name:'body', link:'xxxxxx', width: '160', height: '160' , top: '0', left: '0'}, {name:'chin', link:'xxxxxx', width: '160', height: '160' , top: '0', left: '0'}, {name:'eyeleft', link:'xxxxxx', width: '16', height: '16' , top: '74', left: '57'}, {name:'eyeright', link:'xxxxxx', width: '16', height: '16' , top: '74', left: '85'}, {name:'eyebrow', link:'xxxxxx', width: '48', height: '48' , top: '52', left: '55'}, {name:'nose', link:'xxxxxx', width: '19', height: '19' , top: '82', left: '70'}, {name:'mouth', link:'xxxxxx', width: '17', height: '17' , top: '96', left: '71'} ]
among
The name field represents the name of a part of a face cartoon
The link field represents the default used element picture for a part of a face cartoon
width/height represents the size of a part of a face cartoon
left/top represents the location of a part of a face cartoon
So let's encapsulate a component in mpvue and see what happens
<template> <div class="preview-layer"> <div class="layer" v-for="(layer, index) in layers" :key="index" :style="{height: layer.height + 'px'||5 + 'px', width: layer.width + 'px'||5 + 'px',left:layer.left + 'px', top: layer.top + 'px'}" :type="layer.type"> <img class="cartoon" :src="layer.link"> </div> </div> </template> <script> /* eslint-disable */ export default { data() { return { layers: [ {name:'hair', link:'xxxxxx', width: '160', height: '160' , top: '0', left: '0'}, {name:'body', link:'xxxxxx', width: '160', height: '160' , top: '0', left: '0'}, {name:'chin', link:'xxxxxx', width: '160', height: '160' , top: '0', left: '0'}, {name:'eyeleft', link:'xxxxxx', width: '16', height: '16' , top: '74', left: '57'}, {name:'eyeright', link:'xxxxxx', width: '16', height: '16' , top: '74', left: '85'}, {name:'eyebrow', link:'xxxxxx', width: '48', height: '48' , top: '52', left: '55'}, {name:'nose', link:'xxxxxx', width: '19', height: '19' , top: '82', left: '70'}, {name:'mouth', link:'xxxxxx', width: '17', height: '17' , top: '96', left: '71'} ] } }, mounted() { }, methods: { } } </script> <style> .preview-layer { width: 100%; height: 300px; position: absolute; } .layer { width: 100%; height: 100%; position: absolute; } .cartoon { width: 100%; height: 100%; } </style>
This makes it easy to achieve the face effect of burst/dither