Features

更新时间:
复制 MD 格式

This topic provides a basic example of how to use the Queen SDK for iOS.

Dynamic download API call example

Important
  1. The built-in resource download service in the Queen retouching menu component is a temporary service provided by Alibaba Cloud. This service is subject to change at any time, and its accessibility and validity are not guaranteed. This service is intended only for feature demonstration in the official demo and must not be used in commercial production environments.

  2. For commercial use, you must replace the download URL with your own resource download server address. Alibaba Cloud does not provide services for this resource download address or offer support for related issues.

Method for customizing resource download URLs

  1. Usage scenarios for the queen_menu menu component.

    // Set the download URL for each resource. [Important: QueenMaterial is a static singleton. You must set the URL before you initialize the menu component.]
    // The MaterialType parameter has six types: MODEL (algorithm), STICKER, LUT (filter), MAKEUP, BACKGROUND (matting background), and FACE_EFFECTS (facial effects).
    // materialUrl is the download URL for the corresponding resource package. The resource package must be compressed into a ZIP file. Place the resource files directly in the root directory. The system automatically scans and loads the resources in the folder after decompression.
    [[QueenMaterial sharedInstance] setMaterialURL:(kQueenMaterialType)type withURL:(NSString *)materialURL]
  2. Use cases for the custom retouching menu component.

    // If the downloaded SDK does not have a built-in model, download the model first. You can initialize the queenEngine only after the model is downloaded.
    - (void)checkModelsAndInitQueenEngine
    {
     // Set the delegate for the resource manager.
     [QueenMaterial sharedInstance].delegate = self;
    
     // Check if the model needs to be downloaded.
     if (![[QueenMaterial sharedInstance] requestMaterial:kQueenMaterialModel])
     {
     // If the model does not need to be downloaded, initialize the engine directly.
     [self initBeautyEngine];
     }
    }
    
    // Download extended resources.
    - (void)downloadExtraResource
    {
     // Set the delegate for the resource manager.
     [QueenMaterial sharedInstance].delegate = self;
    
     // Check if sticker resources need to be downloaded.
     if (![[QueenMaterial sharedInstance] requestMaterial:kQueenMaterialModel])
     {
     // If no download is needed, get the resource directory path directly.
     NSString *stickerResPath = [[QueenMaterial sharedInstance] getMaterialPath:kQueenMaterialSticker];
     NSLog(@"stickers Path:%@ \n", stickerResPath);
     }
    }
    
    #pragma mark - QueenMaterialDelegate
    
    - (void)queenMaterialOnReady:(kQueenMaterialType)type
    {
     // Resource downloaded successfully.
     if (type == kQueenMaterialModel)
     {
     // Model downloaded successfully. Initialize the engine.
     [self initBeautyEngine];
     }
     else if (type == kQueenMaterialSticker)
     {
     // Sticker resources downloaded successfully. Get the resource directory path.
     NSString *stickerResPath = [[QueenMaterial sharedInstance] getMaterialPath:kQueenMaterialSticker];
     NSLog(@"stickers Path:%@ \n", stickerResPath);
     }
    }
    
    - (void)queenMaterialOnProgress:(kQueenMaterialType)type withCurrentSize:(int)currentSize withTotalSize:(int)totalSize withProgess:(float)progress
    {
     // Resource download progress callback.
    }
    
    - (void)queenMaterialOnError:(kQueenMaterialType)type
    {
     // Resource download error.
    }

Queen SDK feature example

Note

If you are upgrading from V1.x.x to V2.0.0 or later, note the following:

If you plan to upgrade the Queen SDK from V1.x.x to V2.0.0 or later, you must submit a new request at Create Application and Bind License to have your LicenseKey and LicenseFile (certificate file) reissued. In the title of your request, specify Reissue Request. We will reissue the LicenseKey and LicenseFile (certificate file) within 48 business hours after we receive your request. If you plan to create a new application and apply for a Queen SDK license, log on to the ApsaraVideo Live or ApsaraVideo VOD console, and then go to SDK Management > My Licenses.

- (void)initBeautyEngine
{
 // Initialize the engine configuration information object.
 QueenEngineConfigInfo *configInfo = [QueenEngineConfigInfo new];

 // Specify whether to automatically set the image rotation angle. For example, if the device screen is locked and images are captured from the camera by default, you can enable this feature.
#if kEnableCustomSettingImgAngle
 configInfo.autoSettingImgAngle = NO;
#else
 configInfo.autoSettingImgAngle = YES;
#endif

 // Set the resource root directory.
 NSString *bundlPath = [[NSBundle mainBundle] bundlePath];
 configInfo.resRootPath = [bundlPath stringByAppendingString:@"/res"];

 // Initialize the engine.
 self.beautyEngine = [[QueenEngine alloc] initWithConfigInfo:configInfo];

 [self testBaseFaceBeauty];
 [self testAdvancedFaceBeauty];
 [self testFaceMakeup];
 [self testFaceShape];
 [self testBodyShape];
 [self testFilter];
 [self testSticker];
 [self testGreenScreenOrBlueScreenCutout];
 [self testAutoFilter];
 [self testGestureDetect];
// [self testBackgroundCutout];
// [self testDebug];
}
- (void)testBaseFaceBeauty
{
 // Enable the skin smoothing and sharpening feature.
 // The third parameter specifies the basic retouching mode. Set it to kBMSkinBuffing_Natural for a more natural effect that preserves more details. Set it to kQueenBeautyFilterModeSkinBuffing_Strong for a more pronounced effect that removes more details.
 [self.beautyEngine setQueenBeautyType:kQueenBeautyTypeSkinBuffing enable:YES mode:kQueenBeautyFilterModeSkinBuffing_Natural];

 // Set the skin smoothing coefficient.
 [self.beautyEngine setQueenBeautyParams:kQueenBeautyParamsSkinBuffing value:0.5f];
 // Set the sharpening coefficient.
 [self.beautyEngine setQueenBeautyParams:kQueenBeautyParamsSharpen value:0.5f];

 // Enable the skin whitening feature.
 [self.beautyEngine setQueenBeautyType:kQueenBeautyTypeSkinWhiting enable:YES];

 // Set the skin whitening coefficient.
 [self.beautyEngine setQueenBeautyParams:kQueenBeautyParamsWhitening value:0.5f];
}

- (void)testAdvancedFaceBeauty
{
 // Enable the advanced retouching feature.
 [self.beautyEngine setQueenBeautyType:kQueenBeautyTypeFaceBuffing enable:YES];

 // Set the eye bag removal coefficient.
 [self.beautyEngine setQueenBeautyParams:kQueenBeautyParamsPouch value:0.5f];
 // Set the nasolabial fold removal coefficient.
 [self.beautyEngine setQueenBeautyParams:kQueenBeautyParamsNasolabialFolds value:0.5f];
 // Set the teeth whitening coefficient.
 [self.beautyEngine setQueenBeautyParams:kQueenBeautyParamsWhiteTeeth value:0.5f];
 // Set the lipstick coefficient.
 [self.beautyEngine setQueenBeautyParams:kQueenBeautyParamsLipstick value:0.5f];
 // Set the blush coefficient.
 [self.beautyEngine setQueenBeautyParams:kQueenBeautyParamsBlush value:0.5f];
 // Set the lipstick hue coefficient.
 [self.beautyEngine setQueenBeautyParams:kQueenBeautyParamsLipstickColorParam value:0.1f];
 // Set the lipstick saturation coefficient.
 [self.beautyEngine setQueenBeautyParams:kQueenBeautyParamsLipstickGlossParam value:0.5f];
 // Set the lipstick brightness coefficient.
 [self.beautyEngine setQueenBeautyParams:kQueenBeautyParamsLipstickBrightnessParam value:0.5f];
 // Set the eye brightening coefficient.
 [self.beautyEngine setQueenBeautyParams:kQueenBeautyParamsBrightenEye value:0.5f];
 // Set the rosy skin coefficient.
 [self.beautyEngine setQueenBeautyParams:kQueenBeautyParamsSkinRed value:0.5f];
 // Set the wrinkle removal coefficient.
 [self.beautyEngine setQueenBeautyParams:kQueenBeautyParamsWrinkles value:0.2f];
 // Set the dullness removal coefficient.
 [self.beautyEngine setQueenBeautyParams:kQueenBeautyParamsBrightenFace value:0.2f];
}

- (void)testSkinHSV
{
 // Enable the HSV adjustment feature.
 [self.beautyEngine setQueenBeautyType:kQueenBeautyTypeHSV enable:YES];

 // Set the saturation coefficient.
 [self.queenEngine setQueenBeautyParams:kQueenBeautyParamsHSVSaturation value:0.2f];
 // Set the contrast coefficient.
 [self.queenEngine setQueenBeautyParams:kQueenBeautyParamsHSVContrast value:0.2f];
}

- (void)testFaceMosaicing
{
 // Enable the face mosaicing feature.
 [self.beautyEngine setQueenBeautyType:kQueenBeautyTypeFaceMosaicing enable:YES];

 // Set the mosaic size coefficient.
 [self.queenEngine setQueenBeautyParams:kQueenBeautyParamsFaceMosaicing value:0.2f];
}

- (void)testFaceMakeup
{ 
 
 // Enable the makeup feature.
 // The third parameter specifies the makeup mode. This parameter currently affects only eyebrows. If you set it to BeautyFilterMode.kBMFaceMakeup_High, the eyebrow shape deformation is more pronounced. If you set it to kQueenBeautyFilterModeFaceMakeup_Baseline, the eyebrow shape deformation is less pronounced.
 [self.beautyEngine setQueenBeautyType:kQueenBeautyTypeMakeup enable:YES mode:kQueenBeautyFilterModeFaceMakeup_Baseline];;

 BOOL makeupWhole = true;
 if (makeupWhole) 
 {
 // Set the full makeup effect. The resource path can also be an absolute path.
 [self.beautyEngine setMakeupWithType:kQueenBeautyMakeupTypeWhole paths:@[@"makeup/whole/vitality.2.31.png"] blendType:kQueenBeautyBlendLabMix];
 // Set the opacity of the full makeup effect. The female parameter is currently set to YES/true. Makeup effects for males are being optimized.
 [self.beautyEngine setMakeupAlphaWithType:kQueenBeautyMakeupTypeWhole female:YES alpha:1.0];
 }
 else
 {
 // Set a partial makeup effect. Note: If you set a partial makeup effect after a full makeup effect is set, the full makeup effect becomes invalid. Full and partial makeup effects cannot coexist. However, you can apply multiple partial makeup effects. A single material is sufficient for a full makeup effect, but you cannot adjust the details of each part.
 // Set the highlight effect. The resource path can also be an absolute path.
 [self.beautyEngine setMakeupWithType:kQueenBeautyMakeupTypeHighlight paths:@[@"makeup/highlight/highlight.2.12.png"] blendType:kQueenBeautyBlendOverlay];
 // Set the opacity of the highlight effect. The female parameter is currently set to YES/true. Makeup effects for males are being optimized.
 [self.beautyEngine setMakeupAlphaWithType:kQueenBeautyMakeupTypeHighlight female:YES alpha:0.4];
 // Set the cosmetic contact lens effect. The resource path can also be an absolute path.
 [self.beautyEngine setMakeupWithType:kQueenBeautyMakeupTypeEyeball paths:@[@"makeup/eyeball/milanda.2.1.png"] blendType:kQueenBeautyBlendLighten];
 // Set the opacity of the cosmetic contact lens effect. The female parameter is currently set to YES/true. Makeup effects for males are being optimized.
 [self.beautyEngine setMakeupAlphaWithType:kQueenBeautyMakeupTypeEyeball female:YES alpha:1.0];
 // Set the lipstick effect. The resource path can also be an absolute path.
 [self.beautyEngine setMakeupWithType:kQueenBeautyMakeupTypeMouth paths:@[@"makeup/mouth_matte/standout.2.31.png"] blendType:kQueenBeautyBlendLabMix];
 // Set the opacity of the lipstick effect. The female parameter is currently set to YES/true. Makeup effects for males are being optimized.
 [self.beautyEngine setMakeupAlphaWithType:kQueenBeautyMakeupTypeMouth female:YES alpha:0.5];
 // Set the aegyo-sal makeup effect. This feature uses built-in materials and does not support customization.
 [self.beautyEngine setMakeupWithType:kQueenBeautyMakeupTypeWocan paths:@[@"makeup/aegyo-sal.png"] blendType:kQueenBeautyBlendCurve];
 // Set the opacity of the aegyo-sal makeup effect. The female parameter is currently set to YES/true. Makeup effects for males are being optimized.
 [self.beautyEngine setMakeupAlphaWithType:kQueenBeautyMakeupTypeWocan female:YES alpha:0.2];
 // Set the eyebrow makeup effect. The resource path can also be an absolute path.
 [self.beautyEngine setMakeupWithType:kQueenBeautyMakeupTypeEyeBrow paths:@[@"makeup/eyebrow/standard_eyebrow.2.31.png"] blendType:kQueenBeautyBlendLabMix];
 // Set the opacity of the eyebrow makeup effect. The female parameter is currently set to YES/true. Makeup effects for males are being optimized.
 [self.beautyEngine setMakeupAlphaWithType:kQueenBeautyMakeupTypeEyeBrow female:YES alpha:0.6];
 // Set the blush effect. The resource path can also be an absolute path.
 [self.beautyEngine setMakeupWithType:kQueenBeautyMakeupTypeBlush paths:@[@"makeup/blush/tipsy.2.31.png"] blendType:kQueenBeautyBlendLabMix];
 // Set the opacity of the blush effect. The female parameter is currently set to YES/true. Makeup effects for males are being optimized.
 [self.beautyEngine setMakeupAlphaWithType:kQueenBeautyMakeupTypeBlush female:YES alpha:0.8];
 // Set the eyeshadow effect. The resource path can also be an absolute path.
 [self.beautyEngine setMakeupWithType:kQueenBeautyMakeupTypeEyeShadow paths:@[@"makeup/eyeshadow/milk_tea_brown.2.31.png"] blendType:kQueenBeautyBlendLabMix];
 // Set the opacity of the eyeshadow effect. The female parameter is currently set to YES/true. Makeup effects for males are being optimized.
 [self.beautyEngine setMakeupAlphaWithType:kQueenBeautyMakeupTypeEyeShadow female:YES alpha:0.7];
 // Set the eyeliner effect. The resource path can also be an absolute path.
 [self.beautyEngine setMakeupWithType:kQueenBeautyMakeupTypeEyeliner paths:@[@"makeup/eyeliner_292929/gentle.2.31.png"] blendType:kQueenBeautyBlendLabMix];
 // Set the opacity of the eyeliner effect. The female parameter is currently set to YES/true. Makeup effects for males are being optimized.
 [self.beautyEngine setMakeupAlphaWithType:kQueenBeautyMakeupTypeEyeliner female:YES alpha:0.5];
 // Set the eyelash effect. The resource path can also be an absolute path. [self.beautyEngine setMakeupWithType:kQueenBeautyMakeupTypeEyelash paths:@[@"makeup/eyelash/wild.2.31.png"] blendType:kQueenBeautyBlendLabMix];
 // Set the opacity of the eyelash effect. The female parameter is currently set to YES/true. Makeup effects for males are being optimized.
 [self.beautyEngine setMakeupAlphaWithType:kQueenBeautyMakeupTypeEyelash female:YES alpha:0.5];
 }
 
// // Clear makeup effects.
// [self.beautyEngine resetAllMakeupType];
 
// // Disable the makeup feature.
// [self.beautyEngine setQueenBeautyType:kQueenBeautyTypeMakeup enable:NO];

/*
We recommend that you use combined makeup instead of full makeup to adjust the details of each part. The following are some combined makeup modes: 
1. Tipsy makeup:
 Eyeshadow (makeup/eyeshadow/milk_tea_brown.2.31.png Opacity: 0.7),
 Eyelash (makeup/eyelash/wild.2.31.png Opacity: 0.5),
 Blush (makeup/blush/tipsy.2.31.png Opacity: 0.8),
 Eyeliner (makeup/eyeliner_292929/gentle.2.31.png Opacity: 0.5),
 Lipstick (makeup/mouth_matte/standout.2.31.png Opacity: 0.5),
 Highlight (makeup/highlight/highlight.2.12.png, Opacity: 0.4) 
2. Freckle makeup:
 Eyeshadow (makeup/eyeshadow/peach_pink.2.31.png Opacity: 0.7),
 Eyelash (makeup/eyelash/wild.2.31.png Opacity: 0.5),
 Blush (makeup/blush/cool.2.31.png Opacity: 0.8),
 Eyeliner (makeup/eyeliner_292929/playful.2.31.png Opacity: 0.5),
 Lipstick (makeup/mouth_bitten/pumpkin.2.31.png Opacity: 0.5),
 Highlight (makeup/highlight/highlight.2.12.png, Opacity: 0.4) 
3. Lively makeup:
 Eyeshadow (makeup/eyeshadow/sweet_orange.2.31.png Opacity: 0.7),
 Eyelash (makeup/eyelash/agile.2.31.png Opacity: 0.5),
 Blush (makeup/blush/sunset.2.31.png Opacity: 0.8),
 Eyeliner (makeup/eyeliner_292929/classy.2.31.png Opacity: 0.5),
 Lipstick (makeup/mouth_bitten/pumpkin.2.31.png Opacity: 0.5),
 Highlight (makeup/highlight/highlight.2.12.png, Opacity: 0.4) 
4. Nightclub makeup:
 Eyeshadow (makeup/eyeshadow/night_rose.2.31.png Opacity: 0.7),
 Eyelash (makeup/eyelash/executive.2.31.png Opacity: 0.5),
 Blush (makeup/blush/girly.2.31.png Opacity: 0.8),
 Eyeliner (makeup/eyeliner_292929/gentle.2.31.png Opacity: 0.5),
 Lipstick (makeup/mouth_moist/classic_red.2.31.png Opacity: 0.5),
 Highlight (makeup/highlight/highlight.2.12.png, Opacity: 0.4)
*/
}

- (void)testFaceShape
{
 // Enable the face shaping feature.
 // The third parameter specifies the face shaping mode. You can set it to kQueenBeautyFilterModeFaceShape_Baseline, kQueenBeautyFilterModeFaceShape_Main,
 kQueenBeautyFilterModeFaceShape_High, or kQueenBeautyFilterModeFaceShape_Max. The intensity of the deformation increases in this order.
 [self.beautyEngine setQueenBeautyType:kQueenBeautyTypeFaceShape enable:YES mode:kQueenBeautyFilterModeFaceShape_Main];

 // Set the eye enlargement coefficient.
 [self.beautyEngine setFaceShape:kQueenBeautyFaceShapeTypeBigEye value:1.0f];
 // Set the hairline coefficient.
 [self.beautyEngine setFaceShape:kQueenBeautyFaceShapeTypeHairLine value:1.0f];
 // Set the smile coefficient.
 [self.beautyEngine setFaceShape:kQueenBeautyFaceShapeTypeSmile value:1.0f];
}

- (void)testBodyShape
{
 // Enable the body shaping feature.
 [self.beautyEngine setQueenBeautyType:kQueenBeautyTypeBodyShape enable:YES];
 // Set the long leg coefficient.
 [self.beautyEngine setFaceShape:kQueenBeautyBodyShapeTypeLongLag value:1.0f];
 // // Set the small head coefficient.
 // [self.beautyEngine setFaceShape:kQueenBeautyBodyShapeTypeSmallHead value:1.0f];
}

- (void)testFilter
{
 // Enable the filter feature.
 [self.beautyEngine setQueenBeautyType:kQueenBeautyTypeLUT enable:YES];

 // Set the filter resource. The path can also be an absolute path.
 [self.beautyEngine setLutImagePath:@"lookups/ly1.png"];
 // Set the filter intensity.
 [self.beautyEngine setQueenBeautyParams:kQueenBeautyParamsLUT value:0.8f];
}

- (void)testSticker
{
 // Add a sticker. The path can also be an absolute path.
 [self.beautyEngine addMaterialWithPath:@"sticker/1"];
// // Add a sticker. Sticker layers are stacked from bottom to top.
// [self.beautyEngine addMaterialWithPath:@"sticker/2"];
// // Remove the sticker.
// [self.beautyEngine removeMaterialWithPath:@"sticker/1"];
// [self.beautyEngine removeMaterialWithPath:@"sticker/2"];
}

- (void)testGreenScreenOrBlueScreenCutout
{
 // Enable the green screen matting feature.
 NSString *backgroundImgPath = @"background/red.png";// The path can also be an absolute path.
 BOOL enableBlue = NO;
 float threshold = 0;
 BOOL autoThreshold = YES;
 [self.beautyEngine setGreenScreen:backgroundImgPath blueScreenEnabled:enableBlue threshold:threshold autoThresholdEnabled:autoThreshold];

// // Enable the blue screen matting feature.
// enableBlue = YES;
// [self.beautyEngine setGreenScreen:backgroundImgPath blueScreenEnabled:enableBlue threshold:threshold autoThresholdEnabled:autoThreshold];

// // Disable the screen matting feature.
// [self.beautyEngine setGreenScreen:nil blueScreenEnabled:enableBlue threshold:threshold autoThresholdEnabled:autoThreshold];
}

- (void)testBackgroundCutout
{
// Before you enable smart matting, you can set its performance mode as needed. Options include auto, best quality, balanced, and best performance. If not set, the default is auto mode.
// [self.beautyEngine setSegmentPerformanceMode:kQueenSegmentPMAuto];

// // Enable portrait background blur.
// [self.beautyEngine setQueenBeautyType:kQueenBeautyTypeBackgroundProcess enable:YES];
// // After this feature is enabled, background blur is on by default. You can use the following API to set the background to transparent. This is suitable for scenarios where the output is used as a foreground for custom background composition.
// [self.beautyEngine setSegmentBackgroundProcessType:kQueenBackgroundTransparent];
// // Disable portrait background blur.
// [self.beautyEngine setQueenBeautyType:kQueenBeautyTypeBackgroundProcess enable:NO];
//
 NSString *backgroundResPath = @"background/static_corridor";// The path can also be an absolute path.
 // Replace the portrait background with a static image. Do not add the same resource repeatedly.
 [self.beautyEngine addMaterialWithPath:backgroundResPath];
// // Cancel setting the portrait background to a static image.
// [self.beautyEngine removeMaterialWithPath:backgroundResPath];
}

- (void)testAutoFilter
{
 // Enable smart dynamic optimization:
 [self.beautyEngine setQueenBeautyType:kQueenBeautyTypeAutoFilter enable:YES];
 // Disable smart dynamic optimization:
 [self.beautyEngine setQueenBeautyType:kQueenBeautyTypeAutoFilter enable:NO];
}
- (void)testGestureDetect
{
 // Enable gesture detection.
 [self.beautyEngine setQueenBeautyType:kQueenBeautyTypeHandGestureDetect enable:YES];
// // Disable gesture detection.
// [self.beautyEngine setQueenBeautyType:kQueenBeautyTypeHandGestureDetect enable:NO];
 // Set the delegate. self.beautyEngine.delegate = self;
}
- (void)testSportDetect
{
 // Enable action detection.
 [self.beautyEngine setQueenBeautyType:kQueenBeautyTypeBodyDetect enable:YES];
 // Clear the action count.
 [self.beautyEngine clearBodySportCount];
 // Set the action type to be counted. 0: Pose detection. 1: Jump rope. 2: Jumping jack. 3: Squat. 4: Arm circle. 5: Diamond stretch. 6: Chest stretch. 7: Sit-up. 8: Push-up. 9: Knee push-up.
 [self.beautyEngine setBodyDetectSportType:0];
 // // Disable action detection.
 // [self.beautyEngine setQueenBeautyType:kQueenBeautyTypeBodyDetect enable:NO];

 // Set the delegate.
 self.beautyEngine.delegate = self;
}

- (void)queenEngine:(QueenEngine *)engine didDetectBodyInfo:(QEBodyInfoData *)bodyInfoData
{
 if (bodyInfoData.bodySportType <= 0)
 {
 /*
 {{1, Normal}, //Upright
 {2, HandsUp}, //Raise both hands
 {3, HandsOnHead}, //Hand heart/Touch head
 {4, LHandUp}, //Raise left hand
 {5, RHandUp}, //Raise right hand
 {6, HandLeft}, //To the left 1
 {7, HandRight}, //To the right 1
 {8, DaShape}, //Star shape
 {9, HandLeft2},//Hands on hips, to the left 2
 {10, HandRight2},//Hands on hips, to the right 2
 {11, SuperLeft}, //Superman left
 {12, SuperRight}, //Superman right
 {13, Akimbo}} //Hands on hips
 */
 NSLog(@"Pose type detected: %ld", (long)bodyInfoData.bodyPoseType);
 }
 else
 {
 NSLog(@"Action type detected: %ld, Action count: %ld", (long)bodyInfoData.bodySportType, (long)bodyInfoData.sportCount);
 }
}
- (void)testReHairColor
{
 // Enable the hair color changing feature.
 [self.beautyEngine setQueenBeautyType:kQueenBeautyTypeHairColor enable:YES];

 // Set the hair color.
 [self.beautyEngine setHairColorWithRed:0.3137254901960784
 withGreen:0.3137254901960784
 withBlue:0.6274509803921569];
/* 
* Reference colors:
* ('blue', [0.3137254901960784, 0.3137254901960784, 0.6274509803921569]) 
* ('purple', [0.6078431372549019, 0.35294117647058826, 0.6274509803921569]) 
* ('sky', [0.3333333333333333, 0.5490196078431373, 0.5490196078431373]) 
* ('yellow', [0.6470588235294118, 0.5294117647058824, 0.35294117647058826]) 
* ('green', [0.37254901960784315, 0.5882352941176471, 0.3137254901960784]) 
* ('original', [0.39215686274509803, 0.3333333333333333, 0.3137254901960784]) 
* ('red', [0.5098039215686274, 0.27450980392156865, 0.27450980392156865]) 
*/
}

- (void)testARWriting
{
 // Enable the AR air writing feature.
 [self.beautyEngine setARWriting:YES mode:0];
}

- (void)testDebug
{
 // Show facial recognition feature points.
 [self.beautyEngine showFaceDetectPoint:YES];
 // Show makeup triangulation information. The makeup feature must be enabled first.
 [self.beautyEngine showMakeupLine:YES];
 // Show hand detection feature points.
 [self.beautyEngine showHandDetectPoint:YES];
}

- (CVPixelBufferRef)getProcessedPixelBufferRefWithCurrentPixelBufferRef:(CVPixelBufferRef)pixelBufferRef
{
 if (self.beautyEngine && pixelBufferRef)
 {
 QEPixelBufferData *bufferData = [QEPixelBufferData new];
 bufferData.bufferIn = pixelBufferRef;
 bufferData.bufferOut = pixelBufferRef;
#if kEnableCustomSettingImgAngle
 bufferData.inputAngle = self.cameraRotate; // You must correctly pass the orientation of pixelBufferRef. Otherwise, facial recognition fails. If you do not know the orientation of pixelBufferRef, see the method for obtaining the value of the cameraRotate property in this demo.
 bufferData.outputAngle = self.cameraRotate; // Usually, this can be the same as the value of inputAngle.
#endif
 // Perform image editing on the pixelBuffer and output the processed buffer.
 kQueenResultCode resultCode = [self.beautyEngine processPixelBuffer:bufferData];// The thread that executes this method must always be the same.
 if (resultCode == kQueenResultCodeOK && bufferData.bufferOut)
 {
 return bufferData.bufferOut;
 }
 else if (resultCode == kQueenResultCodeInvalidLicense)
 {
 NSLog(@"License verification failed.");
 }
 else if (resultCode == kQueenResultCodeInvalidParam)
 {
 NSLog(@"Invalid parameter.");
 }
 else if (resultCode == kQueenResultCodeNoEffect)
 {
 NSLog(@"No effects are enabled.");
 }
 return pixelBufferRef;
 }
 else
 {
 return pixelBufferRef;
 }
}

- (void)captureReset
 {
 if (self.beautyEngine)
 {
 // Release queen. Make sure the current thread is the same as the one that executes processPixelBuffer:.
 [self.beautyEngine destroyEngine];
 self.beautyEngine = nil;
 }
}

- (void)captureBegin
{
#if kEnableCustomSettingImgAngle
 [self startRetainCameraRotate];
#endif
}

- (void)captureEnd
{
#if kEnableCustomSettingImgAngle
 [self stopRetainCameraRotate];
#endif
}

#pragma mark - QueenEngineDelegate

- (void)queenEngine:(QueenEngine *)engine didDetectGesture:(QEGestureData *)gestureData
{
 NSLog(@"Gesture type detected: %ld, Action type: %d", (long)gestureData.gesture, gestureData.action);
}

Data and texture separation call example

/**
Notify QueenEngine to process the callback texture.
*/
- (int)onProcessTexture:(int)texture textureWidth:(int)width textureHeight:(int)height
{
 if (self.pushConfig.beautyOn && nil != self.queenEngine) {
 QETextureData* textureData = [[QETextureData alloc] init];
 textureData.inputTextureID = texture;
 textureData.width = width;
 textureData.height = height;
 kQueenResultCode result = [self.queenEngine processTexture:textureData];
 if (result != kQueenResultCodeOK) {
 NSLog(@"queen beauty processTexture error. code: %lu", result);
 }
 return textureData.outputTextureID;
 }
 return texture;
}

/**
Notify QueenEngine to detect and process the callback.
*/
- (long)onDetectorProcessData:(long)data w:(int)w h:(int)h rotation:(int)rotation format:(int)format
{
 if (self.pushConfig.beautyOn && nil != self.queenEngine) {
 [self.beautyEngine updateInputDataAndRunAlg:(uint8_t*)data
 withImgFormat:(kQueenImageFormat)(format)
 withWidth:w
 withHeight:h
 withStride:0
 withInputAngle:rotation
 withOutputAngle:rotation
 withFlipAxis:0];
 }
 return data;
}

/**
Notify QueenEngine to destroy the callback.
*/
- (void)onDestory
{
 if (nil != self.beautyEngine) {
 [self.beautyEngine destroyEngine];
 self.beautyEngine = nil;
 }
}