UyaliBeautySDK documentation
UyaliBeautySDK integration docs
UyaliBeautySDK is built for real-time video scenarios such as camera, live streaming, short video, meetings, and online teaching. It provides base beauty, detailed face reshape, body shaping, makeup overlay, face landmarks, and body pose capabilities. This document covers platform integration, license checks, frame-processing entry points, and the names, ranges, and effects of all adjustable parameters.
Integration overview
The docs use real code from the UyaliBeautySDK demo: create and reuse one engine instance, send camera frames, image frames, or textures into the SDK, and update only the current parameter state on that same engine instance.
Each platform section shows how the demo holds the engine instance and writes License and parameter state into the same instance.
Supported input formats are documented in each platform section, so users only need to read the platform they are integrating.
When sliders, switches, presets, or makeup selections change, call the parameter APIs only. The SDK uses the new values on later frames.
The SDK engine is not an object that should be re-created every time a parameter changes. Reuse one instance for a preview, live stream, meeting, or image-editing flow, then update parameters after frame processing is connected.
Runtime model
The SDK should not be initialized again for each parameter entry point. The demo keeps one engine instance for a preview or editing flow, starts frame processing first, and applies all later parameter updates to the same instance.
| Item | Description |
|---|---|
| Engine instance | The SDK does not require a process-wide singleton. Each platform section shows the instance ownership used by the demo. |
| Initialization count | Create one engine instance for a camera preview, live stream, meeting, or image-editing flow and reuse it inside that flow. Do not re-create it per frame or per slider change. |
| License loading | After the License is loaded into the current engine instance, the SDK records authorization status and module capabilities. The app layer can query capabilities to decide which features to show. |
| Parameter state | Parameters are stored on the current engine instance. After frame processing is connected, slider changes only need to update parameters; later frames use the new values. |
| Frame processing | The process APIs handle the current input frame, read the parameter state on the current engine instance, and output the processed image. |
After initialization and frame processing are connected, beauty, reshape, body, and makeup adjustments are all parameter writes on the same engine instance. The SDK reads those values on the next processed frame.
iOS integration
The iOS demo uses UyaliBeautyEngine to process RGBA CVPixelBuffer camera output directly. The engine instance is held by the page, and parameter updates continue to write into that same instance.
UyaliBeautyEngine, named filter in the demo.
RGBA CVPixelBuffer from AVCapture or a video frame-processing pipeline.
process(pixelBuffer:) processes in place, while processWithOutput(pixelBuffer:) returns an output frame.
Demo integration code
// BeautyFilterController.swift excerpt
import UIKit
import UyaliBeautySDK
class BeautyFilterController: UIViewController, PFCameraDelegate {
private var camera: PFCamera!
private var openGLView: PFOpenGLView!
private let filter = UyaliBeautyEngine()
override func viewDidLoad() {
super.viewDidLoad()
camera = PFCamera()
camera.delegate = self
camera.startCapture()
}
func didOutputVideoSampleBuffer(_ sampleBuffer: CMSampleBuffer!) {
guard let sampleBuffer = sampleBuffer,
let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else {
return
}
filter.process(pixelBuffer: pixelBuffer)
openGLView.display(pixelBuffer)
}
}License
let result = filter.activateLicense(licenseString)
if result.status != .valid {
print(result.message)
}Parameter updates
// FaceBeautyDelegate callback excerpt
func getBeautyDeltaValue(value: Float, type: Int) {
if type == 100 {
filter.white_delta = value
} else if type == 101 {
filter.skin_delta = value
} else if type == 102 {
filter.eyeBright_delta = value
} else if type == 103 {
filter.teethBright_delta = value
} else if type == 104 {
filter.darkCircle_delta = value
}
}Android integration
The Android demo uses a texture pipeline for real-time preview. UyaliBeautyTextureProcessor holds the same UyaliBeautyEngine instance, receives the camera OES texture, and outputs the processed texture.
Call textureProcessor.engine() to get the current UyaliBeautyEngine.
External OES Texture, suitable for Camera preview, GL rendering, and pre-push processing.
Supports RGBA ByteBuffer, Bitmap, Camera Image, and YUV420.
Demo integration code
// UyaliBeautyView.java excerpt
public class UyaliBeautyView extends GLSurfaceView implements GLSurfaceView.Renderer {
private final UyaliBeautyTextureProcessor textureProcessor;
private final UyaliBeautyEngine engine;
public UyaliBeautyView(Context context, AttributeSet attrs) {
super(context, attrs);
textureProcessor = new UyaliBeautyTextureProcessor(context);
engine = textureProcessor.engine();
setEGLContextClientVersion(3);
setRenderer(this);
setRenderMode(RENDERMODE_WHEN_DIRTY);
}
private void drawCameraFrame() {
UyaliBeautyTextureInput input = UyaliBeautyTextureInput.externalOes(
oesTextureId,
transform,
viewWidth,
viewHeight,
sourceWidth,
sourceHeight,
mirrorFrontCamera,
cameraSurfaceTexture.getTimestamp(),
true);
UyaliBeautyTextureFrame outputFrame = textureProcessor.process(input);
if (outputFrame != null && outputFrame.isValid()) {
drawTexture2dToViewport(outputFrame.textureId(),
UyaliBeautyTextureInput.IDENTITY_TRANSFORM,
viewWidth,
viewHeight,
outputFrame.width(),
outputFrame.height(),
true);
}
}
}CPU / image input
UyaliBeautyEngine beauty = beautyView.engine(); beauty.processRgbaInPlace(rgbaBuffer, width, height); Bitmap output = beauty.processBitmap(bitmap); UyaliBeautyFrame frame = beauty.process(image, rotationDegrees);
License
UyaliBeautyEngine engine = currentEngine();
UyaliBeautyLicenseResult result = engine.activateLicense(licenseText);
if (result.getStatus() != UyaliBeautyLicenseStatus.VALID) {
Log.w("UyaliBeauty", result.getMessage());
}Parameter updates
// MainActivity.java: SeekBar parameter update excerpt
private void applyFeatureValue(Feature feature, int progress, TextView valueLabel) {
float actual = feature.signed ? progress - 50f : progress;
valueLabel.setText(displayValue(progress, feature.signed));
UyaliBeautyEngine engine = currentEngine();
if (engine != null) {
engine.setParameter(feature.parameter, actual);
}
updateCameraProcessingMode();
requestCurrentRender();
}HarmonyOS integration
The HarmonyOS demo holds UyaliBeautyEngine at page level. The real-time camera pipeline can use processCameraFrame, while PixelMap images or preview frames can use processPixelMapInPlace.
Create private engine: UyaliBeautyEngine = new UyaliBeautyEngine() in the page.
Supports NativeImage / YUV420 camera frames and can output to Surface.
Supports RGBA ArrayBuffer and editable PixelMap.
Demo integration code
// CameraBeautyPage.ets excerpt
import { UyaliBeautyEngine } from 'uyali_beauty_sdk';
@Entry
@Component
struct CameraBeautyPage {
private engine: UyaliBeautyEngine = new UyaliBeautyEngine();
private async handleCameraFrame(frame: CameraFrame): Promise<void> {
syncBeautyState(this.engine, this.values, this.makeupTypes, this.frontCamera);
if (frame.kind === 'yuv420') {
const framePayload = this.cameraFramePayload(frame);
const result = this.engine.processCameraFrame(framePayload);
this.status = result.ok ? 'Beauty processing' : 'Current frame failed';
return;
}
const pixelMap = frame.pixelMap;
const ok = await this.engine.processPixelMapInPlace(pixelMap);
this.status = ok ? 'Beauty processing' : 'Current frame failed';
}
}License
import { UyaliBeautyLicenseStatus } from 'uyali_beauty_sdk';
const result = this.engine.loadLicenseFromRawfile(context, 'uyali/license.lic');
if (result.status !== UyaliBeautyLicenseStatus.VALID) {
console.info(result.message);
}Parameter updates
// BeautyCatalog.ets: page state sync to SDK excerpt
export function syncBeautyState(engine: UyaliBeautyEngine, values: Map<string, number>,
makeupTypes: Map<string, number>, frontCamera: boolean = false): void {
engine.setCameraFacing(frontCamera);
BEAUTY_ITEMS.forEach((item: BeautyItem) => {
engine.setParameter(item.parameter, values.get(item.parameter) ?? item.defaultValue);
});
MAKEUP_GROUPS.forEach((group: MakeupGroup) => {
engine.setParameter(group.parameter, values.get(group.parameter) ?? 0);
engine.setMakeupType(group.typeParameter, makeupTypes.get(group.typeParameter) ?? 0);
});
}License
The SDK supports local signature verification. After app startup, load the License and check whether the authorization is valid. Without a commercial License, whitening and smoothing are free without time limits; all other features can be tried for 120 seconds after SDK initialization.
| Module | Related parameters | Capability scope |
|---|---|---|
WHITEN | white / white_delta | Whitening |
SMOOTH | skin / skin_delta | Smoothing |
BEAUTY | eyeBright, teethBright, darkCircle | Bright eyes, teeth whitening, dark circle reduction |
RESHAPE | Detailed face reshape parameters | Face shape, facial features, brows, eyes, nose, and lips |
BODY | Body shaping parameters | Body, waist, legs, shoulders, and neck adjustments |
MAKEUP | Makeup intensity and type | Eyebrow, eyeshadow, colored contacts, blush, lipstick |
FACE_LANDMARKS | Face detection output | Face landmarks and contour information |
BODY_POSE | Body detection output | Body keypoints and segmented contour information |
DEBUG_OUTPUTS | Debug outputs | Detection information and debug data |
CUSTOM_MAKEUP_ASSETS | Custom makeup assets | Replace or extend makeup resources |
Beauty
The table below lists base beauty parameters. They are not SDK initialization steps; they are usually written from sliders, switches, presets, or config.
| Feature | iOS parameter | Android / HarmonyOS parameter | Range | Effect |
|---|---|---|---|---|
| Whitening | white_delta | white | 0-100 | Improves skin brightness and translucency. 0 disables the effect. |
| Smoothing | skin_delta | skin | 0-100 | Reduces skin texture and noise while preserving facial edges. 0 disables the effect. |
| Bright eyes | eyeBright_delta | eyeBright | 0-100 | Enhances eye whites and catchlights for clearer eyes. |
| Teeth whitening | teethBright_delta | teethBright | 0-100 | Brightens the teeth area, suitable for selfies and live streaming. |
| Dark circle reduction | darkCircle_delta | darkCircle | 0-100 | Softens under-eye darkness for a fresher facial state. |
Face reshape
Face reshape depends on face landmark detection and fits selfie, live, and short-video scenes. Products usually provide natural presets first, then allow users to tune individual parameters.
| Feature | iOS parameter | Android / HarmonyOS parameter | Range | Effect |
|---|---|---|---|---|
| Head size | headReduce_delta | headReduce | 0-100 | Reduces the overall head contour, suitable for half-body and full-body shots. |
| Face slimming | faceThin_delta | faceThin | 0-100 | Narrows the cheek contour and enhances facial lines. |
| Face narrowing | faceNarrow_delta | faceNarrow | 0-100 | Compresses face width for a narrower face shape. |
| V-line | faceV_delta | faceV | 0-100 | Strengthens the V-shaped line from jaw to chin. |
| Small face | faceSmall_delta | faceSmall | 0-100 | Reduces the overall face area, more comprehensive than face slimming alone. |
| Chin | chin_delta | chin | -50-50 | Negative values shorten the chin; positive values lengthen it. |
| Forehead | forehead_delta | forehead | -50-50 | Negative values lower forehead height; positive values increase it. |
| Cheekbones | cheekbone_delta | cheekbone | -50-50 | Negative values soften outward cheekbones; positive values enhance the contour. |
| Eye enlargement | eyeBig_delta | eyeBig | 0-100 | Enlarges the eye area for more expressive eyes. |
| Eye distance | eyeDistance_delta | eyeDistance | -50-50 | Negative values bring eyes closer; positive values move them apart. |
| Inner eye corner | eyeCorner_delta | eyeCorner | 0-100 | Adjusts inner eye corner openness and lengthens the perceived eye shape. |
| Lower eyelid | eyelidDown_delta | eyelidDown | 0-100 | Expands lower eyelid space for a rounder eye shape. |
| Nose slimming | noseThin_delta | noseThin | 0-100 | Narrows the bridge and nose tip. |
| Nose wing | noseWing_delta | noseWing | 0-100 | Narrows the nose wing area and reduces horizontal spread. |
| Nose length | noseLong_delta | noseLong | -50-50 | Negative values shorten the nose; positive values lengthen it. |
| Nose root | noseRoot_delta | noseRoot | 0-100 | Enhances the nose bridge root and improves bridge depth. |
| Eyebrow distance | eyebrowDistance_delta | eyebrowDistance | -50-50 | Negative values bring brows closer; positive values move them apart. |
| Eyebrow thickness | eyebrowThin_delta | eyebrowThin | -50-50 | Negative values thin the brows; positive values thicken them. |
| Mouth shape | mouth_delta | mouth | -50-50 | Negative values reduce mouth size; positive values enlarge it. |
Body shaping
Body shaping depends on body keypoints and contour detection. It fits standing, half-body, and full-body shots. For multi-person or occluded scenes, lower defaults can avoid excessive distortion.
| Feature | iOS parameter | Android / HarmonyOS parameter | Range | Effect |
|---|---|---|---|---|
| Body slimming | bodySlim_delta | bodySlim | 0-100 | Narrows the overall body contour. |
| Waist slimming | waistSlim_delta | waistSlim | 0-100 | Tightens the waist lines on both sides. |
| Leg slimming | legSlim_delta | legSlim | 0-100 | Narrows the horizontal leg contour. |
| Shoulder narrowing | shoulderNarrow_delta | shoulderNarrow | 0-100 | Narrows shoulder width. |
| Arm slimming | armSlim_delta | armSlim | 0-100 | Narrows upper-arm and forearm areas. |
| Calf refinement | calfSlim_delta | calfSlim | 0-100 | Refines the outer calf contour. |
| Abdomen slimming | abdomenSlim_delta | abdomenSlim | 0-100 | Tightens the abdomen contour. |
| Long legs | legLong_delta | legLong | 0-100 | Stretches leg proportions. |
| Height | bodyHeight_delta | bodyHeight | 0-100 | Stretches overall body height. |
| Leg shape | legShape_delta | legShape | 0-100 | Optimizes leg curvature and outward spread. |
| Swan neck | neckLength_delta | neckLength | 0-100 | Lengthens the neck line. |
| Right-angle shoulders | shoulderShape_delta | shoulderShape | 0-100 | Adjusts the neck-shoulder angle for straighter shoulders. |
Makeup parameters
Makeup is controlled by type plus intensity. The type is usually set when users choose makeup or switch presets. Type 0 means no makeup asset; intensity 0 hides the effect even if a type is selected.
| Feature | iOS parameter | Android / HarmonyOS parameter | Range | Effect |
|---|---|---|---|---|
| Eyebrow intensity | makeup_eyebrow_delta | makeupEyebrow | 0-100 | Controls eyebrow makeup overlay intensity; use with an eyebrow type. |
| Eyeshadow intensity | makeup_eyeshadow_delta | makeupEyeshadow | 0-100 | Controls eyeshadow opacity and blending strength. |
| Colored contacts intensity | makeup_pupil_delta | makeupPupil | 0-100 | Controls colored contacts overlay intensity. |
| Blush intensity | makeup_blush_delta | makeupBlush | 0-100 | Controls blush overlay intensity. |
| Lipstick intensity | makeup_rouge_delta | makeupRouge | 0-100 | Controls lip color overlay intensity. |
Makeup type values
| Feature | iOS type parameter | Android / HarmonyOS type parameter | Range | Effect | Values |
|---|---|---|---|---|---|
| Eyebrow type | makeup_eyebrow_type | makeupEyebrowType | 0-10 | Selects eyebrow assets. 0 means no eyebrow makeup. | 0 eyebrow_none1 eyebrow_biaozhun2 eyebrow_cupin3 eyebrow_juanyan4 eyebrow_liuxing5 eyebrow_liuye6 eyebrow_qiubo7 eyebrow_wanyue8 eyebrow_xinyue9 eyebrow_yesheng10 eyebrow_yuanshan |
| Eyeshadow type | makeup_eyeshadow_type | makeupEyeshadowType | 0-11 | Selects eyeshadow assets. 0 means no eyeshadow makeup. | 0 eyeshadow_none1 eyeshadow_dadise2 eyeshadow_fuguse3 eyeshadow_fangtangfen4 eyeshadow_huoliju5 eyeshadow_jinzongse6 eyeshadow_pengkezong7 eyeshadow_tianchengse8 eyeshadow_xingguangfen9 eyeshadow_yanfense10 eyeshadow_yeqiangweise11 eyeshadow_yuanqicheng |
| Colored contacts type | makeup_pupil_type | makeupPupilType | 0-12 | Selects colored contacts assets. 0 means no contacts makeup. | 0 pupil_none1 pupil_jiaopianzong2 pupil_mitangzong3 pupil_xingyelan4 pupil_jizhouhei5 pupil_wuraohui6 pupil_chunrifen7 pupil_tianchalv8 pupil_siyecaolv9 pupil_kuangyelan10 pupil_qiangweifenhui11 pupil_haifenglan12 pupil_yueqiuzong |
| Blush type | makeup_blush_type | makeupBlushType | 0-36 | Selects blush assets. 0 means no blush makeup. | 0 blush_none1 blush_wugu_naixingse2 blush_wugu_naijuse3 blush_wugu_mitaoju4 blush_wugu_yanxunmeigui5 blush_wugu_niunaicaomei6 blush_chayi_naixingse7 blush_chayi_naijuse8 blush_chayi_mitaoju9 blush_chayi_yanxunmeigui10 blush_chayi_niunaicaomei11 blush_chulian_naixingse12 blush_chulian_naijuse13 blush_chulian_mitaoju14 blush_chulian_yanxunmeigui15 blush_chulian_niunaicaomei16 blush_chunqing_naixingse17 blush_chunqing_naijuse18 blush_chunqing_mitaoju19 blush_chunqing_yanxunmeigui20 blush_chunqing_niunaicaomei21 blush_qiji_naixingse22 blush_qiji_naijuse23 blush_qiji_mitaoju24 blush_qiji_yanxunmeigui25 blush_qiji_niunaicaomei26 blush_shaonv_naixingse27 blush_shaonv_naijuse28 blush_shaonv_mitaoju29 blush_shaonv_yanxunmeigui30 blush_shaonv_niunaicaomei31 blush_wugu_makalongfen32 blush_chayi_makalongfen33 blush_chulian_makalongfen34 blush_chunqing_makalongfen35 blush_qiji_makalongfen36 blush_shaonv_makalongfen |
| Lipstick type | makeup_rouge_type | makeupRougeType | 0-12 | Selects lipstick assets. 0 means no lip makeup. | 0 rouge_none1 rouge_meizise2 rouge_doushafen3 rouge_fuguse4 rouge_guimeihong5 rouge_jiangguose6 rouge_nanguase7 rouge_shiliuhong8 rouge_mitaose9 rouge_shanhuse10 rouge_xingguanghong11 rouge_anyezi12 rouge_shaonvfen |
iOS example
beauty.makeup_eyebrow_type = .eyebrow_xinyue beauty.makeup_eyebrow_delta = 45 beauty.makeup_rouge_type = .rouge_mitaose beauty.makeup_rouge_delta = 35
Android example
beauty.setMakeupType("makeupEyebrowType", 8);
beauty.setParameter("makeupEyebrow", 45f);
beauty.setMakeupType("makeupRougeType", 8);
beauty.setParameter("makeupRouge", 35f);HarmonyOS example
beauty.setMakeupType('makeupEyebrowType', 8);
beauty.setParameter('makeupEyebrow', 45);
beauty.setMakeupType('makeupRougeType', 8);
beauty.setParameter('makeupRouge', 35);I/O and debug
Camera pipelines should confirm orientation and mirroring before passing data to the SDK. Related APIs and input formats are documented in the platform sections.
resetAllFilters restores beauty, reshape, body, and makeup parameters to the default disabled state.
After the corresponding capability is licensed, you can read the latest face landmarks, body keypoints, contour labels, and debug information for display or diagnostics.
FAQ
- Can parameters exceed the documented ranges?
- The app UI should keep values within the documented ranges to avoid uncontrolled distortion across platforms or input resolutions.
- Why does makeup not appear after selecting a type?
- Set both type and intensity, and confirm the License includes the MAKEUP capability. Type 0 or intensity 0 hides the makeup.
- Why do some advanced effects stop working after a while without a License?
- Without a commercial License, features except whitening and smoothing provide a 120-second trial. Read getLicenseTrialSecondsRemaining or the iOS equivalent to get remaining time.
