All Products
Search
Document Center

ApsaraVideo Live:Integrate Queen SDK for macOS

Last Updated:Jun 29, 2023

This topic describes how to use and integrate Queen SDK for macOS to implement face retouching effects. This topic also provides sample code for using Queen SDK for macOS.

Prerequisites

A development environment is set up. The following table describes the requirements for the development environment.

Item

Description

macOS High Sierra

macOS High Sierra 10.13 or later.

Xcode

Xcode 9.0 or later. To download Xcode, visit Mac App Store.

Integration methods

Only local integration is supported.

  1. Download and decompress the sample project. Obtain the queen.framework file.

  2. Open Xcode and select your project target. Under the General tab, add the framework file in the Frameworks, Libraries, and Embedded Content section and set Embed to Embed & Sign for the framework.

Configure the license

Make sure that you have obtained a license of Queen SDK in advance. For more information, see Obtain a license of Queen SDK. After you obtain a license, perform the following steps to configure the LicenseKey and LicenseFile in the project.

Note
  • If you integrate Queen SDK of ApsaraVideo Live and the short video SDK of ApsaraVideo VOD at the same time, the two SDKs have the same LicenseKey and LicenseFile. You only need to configure the LicenseKey and LicenseFile once. Make sure that you use the latest license file.

  • If the SDK that you purchased is updated or needs to be renewed, you must first use the following steps to update the license file:

    1. Obtain the latest license. For more information, see Obtain a license of Queen SDK.

    2. After you obtain the latest license file, perform the steps to configure the license.

Import the license file to the project and add the following keys to the Info.plist file:

  • AlivcLicenseKey: The value of this key is the value of LicenseKey. Example: MoCTfuQ391Z01****8f8745e23c8a457a8ff8d5faedc1****.

  • AlivcLicenseFile: The value of this key is the path of the license file that is relative to mainBundle. Example:AliVideoCert_164933454****.crt.

Sample code of Queen SDK

- (void)initBeautyEngine
{
    // Initialize the configurations of QueenEngine.
    QueenEngineConfigInfo *configInfo = [QueenEngineConfigInfo new];

    Specify the licenseKey and licenseFile parameters. Alternatively, add the AlivcLicenseKey and AlivcLicenseFile fields in the Info.plist file and specify the corresponding values for the fields. The two fields are of the string type. The license key and license file specified in configInfo take precedence over those specified in the Info.plist file.
    configInfo.licenseKey = @"xxx";
    The .crt file is equivalent to the license file in the mainBundlePath and is located in the root directory. You can directly enter the name of the .crt file. 
    configInfo.licenseFile = @"AliVideoCert.crt";

    // Specify the root directory for resources.
    NSString *bundlPath = [[NSBundle mainBundle] bundlePath];
    bundlPath = [bundlPath stringByAppendingPathComponent:@"Contents/Resources/res"];
    configInfo.resRootPath = bundlPath;

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

    [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 skin smoothing and image sharpening.
    // Configure the mode parameter to specify a basic retouching mode. If you set this parameter to kBMSkinBuffing_Natural, the retouching effect is more natural and shows more details. If you set this parameter to kQueenBeautyFilterModeSkinBuffing_Strong, the effect is more exaggerated and has more details removed. 
    [self.beautyEngine setQueenBeautyType:kQueenBeautyTypeSkinBuffing enable:YES mode:kQueenBeautyFilterModeSkinBuffing_Natural];

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

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

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

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

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

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

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

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

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

- (void)testFaceMakeup
{                                          
 
    // Enable makeup.
    // The mode parameter specifies a makeup mode. This parameter takes effect only on eyebrows. If you set this parameter to BeautyFilterMode.kBMFaceMakeup_High, the deformation level of eyebrows is high. If you set this parameter to kQueenBeautyFilterModeFaceMakeup_Baseline,
       the deformation level of eyebrows is low.
    [self.beautyEngine setQueenBeautyType:kQueenBeautyTypeMakeup enable:YES mode:kQueenBeautyFilterModeFaceMakeup_Baseline];;

    BOOL makeupWhole = true;
    if (makeupWhole)    
    {
    // Set makeup effects for the full face. The path of the resource can be an absolute path.
    [self.beautyEngine setMakeupWithType:kQueenBeautyMakeupTypeWhole paths:@[@"makeup/whole/huoli.2.31.png"] blendType:kQueenBeautyBlendLabMix];
   // Set the transparency of full face makeup effects. The value of the female parameter is YES/true. The effects for male makeup are still being optimized.
   [self.beautyEngine setMakeupAlphaWithType:kQueenBeautyMakeupTypeWhole female:YES alpha:1.0];
   }
   else
   {
   // Set partial makeup effects. (Note: If full face makeup is configured, the configuration for full face makeup becomes invalid after a partial makeup effect is set. Full face makeup and partial makeup effects cannot coexist, but all partial makeup effects can be applied at the same time. For full face makeup, you can set a single makeup material to apply makeup to the entire face but cannot adjust the details of each part of the face.
   // Set the highlight effect for the full face. The path of the resources can be an absolute path.
    [self.beautyEngine setMakeupWithType:kQueenBeautyMakeupTypeHighlight paths:@[@"makeup/highlight/highlight.2.12.png"] blendType:kQueenBeautyBlendOverlay];
   // Set the transparency of the highlight effect. The value of the female parameter is YES/true. The effect for male makeup is still being optimized.
   [self.beautyEngine setMakeupAlphaWithType:kQueenBeautyMakeupTypeHighlight female:YES alpha:0.4];
   // Set the colored eye contacts effect. The path of the resources can be an absolute path.
   [self.beautyEngine setMakeupWithType:kQueenBeautyMakeupTypeEyeball paths:@[@"makeup/eyeball/milanda.2.1.png"] blendType:kQueenBeautyBlendLighten];
   // Set the transparency of the colored eye contacts effect. The value of the female parameter is YES/true. The effect for male makeup is still being optimized.
   [self.beautyEngine setMakeupAlphaWithType:kQueenBeautyMakeupTypeEyeball female:YES alpha:1.0];
   // Set lipstick effect. The path of the resources can be an absolute path.
   [self.beautyEngine setMakeupWithType:kQueenBeautyMakeupTypeMouth paths:@[@"makeup/mouth_wumian/standout.2.31.png"] blendType:kQueenBeautyBlendLabMix];
   // Set the transparency of the lipstick effect. The value of the female parameter is YES/true. The effect for male makeup is still being optimized.
   [self.beautyEngine setMakeupAlphaWithType:kQueenBeautyMakeupTypeMouth female:YES alpha:0.5];
   // Set the aegyo-sal effect. Built-in materials are used and custom materials are not supported.
   [self.beautyEngine setMakeupWithType:kQueenBeautyMakeupTypeWocan paths:@[@"makeup/wocan.png"] blendType:kQueenBeautyBlendCurve];
   // Set the transparency of the aegyo-sal effect. The value of the female parameter is YES/true. The effect for male makeup is still being optimized.
   [self.beautyEngine setMakeupAlphaWithType:kQueenBeautyMakeupTypeWocan female:YES alpha:0.2];
   // Set the eyebrow effect. The path of the resources can be an absolute path.
   [self.beautyEngine setMakeupWithType:kQueenBeautyMakeupTypeEyeBrow paths:@[@"makeup/eyebrow/biaozhunmei.2.31.png"] blendType:kQueenBeautyBlendLabMix];
   // Set the transparency of the eyebrow effect. The value of the female parameter is YES/true. The effect for male makeup is still being optimized.
   [self.beautyEngine setMakeupAlphaWithType:kQueenBeautyMakeupTypeEyeBrow female:YES alpha:0.6];
    // Set the blush effect. The path of the resources can be an absolute path.
   [self.beautyEngine setMakeupWithType:kQueenBeautyMakeupTypeBlush paths:@[@"makeup/blush/weixun.2.31.png"] blendType:kQueenBeautyBlendLabMix];
   // Set the transparency of the blush effect. The value of the female parameter is YES/true. The effect for male makeup is still being optimized.
   [self.beautyEngine setMakeupAlphaWithType:kQueenBeautyMakeupTypeBlush female:YES alpha:0.8];
    // Set the eye shadow effect. The path of the resources can be an absolute path.
   [self.beautyEngine setMakeupWithType:kQueenBeautyMakeupTypeEyeShadow paths:@[@"makeup/eyeshadow/naichazong.2.31.png"] blendType:kQueenBeautyBlendLabMix];
    // Set the transparency of the eye shadow effect. The value of the female parameter is YES/true. The effect for male makeup is still being optimized.
   [self.beautyEngine setMakeupAlphaWithType:kQueenBeautyMakeupTypeEyeShadow female:YES alpha:0.7];
    // Set the eyeliner effect. The path of the resources can be an absolute path.
   [self.beautyEngine setMakeupWithType:kQueenBeautyMakeupTypeEyeliner paths:@[@"makeup/eyeliner_292929/wenrou.2.31.png"] blendType:kQueenBeautyBlendLabMix];
    // Set the transparency of the eyeliner effect. The value of the female parameter is YES/true. The effect for male makeup is still being optimized.
   [self.beautyEngine setMakeupAlphaWithType:kQueenBeautyMakeupTypeEyeliner female:YES alpha:0.5];
    // Set the eyelash effect. The path of the resources can be an absolute path.        [self.beautyEngine setMakeupWithType:kQueenBeautyMakeupTypeEyelash paths:@[@"makeup/eyelash/yesheng.2.31.png"] blendType:kQueenBeautyBlendLabMix];
    // Set the transparency of the eyelash effect. The value of the female parameter is YES/true. The effect for male makeup is still being optimized.
        [self.beautyEngine setMakeupAlphaWithType:kQueenBeautyMakeupTypeEyelash female:YES alpha:0.5];
    }
    
//    // Clear all makeup effects.
//    [self.beautyEngine resetAllMakeupType];
    
// // Disable makeup effects.
//    [self.beautyEngine setQueenBeautyType:kQueenBeautyTypeMakeup enable:NO];

/*
We recommend that you use mixed makeup. You can adjust the details of each part of the face. The following types of mixed makeup are provided:    
1. Tipsy makeup:
     For eye shadow, the path is makeup/eyeshadow/naichazong.2.31.png and the transparency is 0.7. 
     For eyelash, the path is makeup/eyelash/yesheng.2.31.png and the transparency is 0.5. 
     For blush, the path is makeup/blush/weixun.2.31.png and the transparency is 0.8. 
     For eyeliner, the path is makeup/eyeliner_292929/wenrou.2.31.png and the transparency is 0.5. 
     For lipstick, the path is makeup/mouth_wumian/standout.2.31.png and the transparency is 0.5. 
     For highlight, the path is makeup/highlight/highlight.2.12.png and the transparency is 0.4. 
2. Freckle makeup:
     For eye shadow, the path is makeup/eyeshadow/taohuafen.2.31.png and the transparency is 0.7. 
     For eyelash, the path is makeup/eyelash/yesheng.2.31.png and the transparency is 0.5. 
     For blush, the path is makeup/blush/cool.2.31.png and the transparency is 0.8. 
     For eyeliner, the path is makeup/eyeliner_292929/guima.2.31.png and the transparency is 0.5. 
     For lipstick, the path is makeup/mouth_yaochun/nanguase.2.31.png and the transparency is 0.5. 
     For highlight, the path is makeup/highlight/highlight.2.12.png and the transparency is 0.4.    
3. Lively makeup:
     For eye shadow, the path is makeup/eyeshadow/tianchengse.2.31.png and the transparency is 0.7. 
     For eyelash, the path is makeup/eyelash/lingdong.2.31.png and the transparency is 0.5. 
     For blush, the path is makeup/blush/luori.2.31.png and the transparency is 0.8. 
     For eyeliner, the path is makeup/eyeliner_292929/qizhi.2.31.png and the transparency is 0.5. 
     For lipstick, the path is makeup/mouth_yaochun/nanguase.2.31.png and the transparency is 0.5. 
     For highlight, the path is makeup/highlight/highlight.2.12.png and the transparency is 0.4.    
4. Nightclub makeup:
     For eye shadow, the path is makeup/eyeshadow/yeqiangwei.2.31.png and the transparency is 0.7. 
     For eyelash, the path is makeup/eyelash/zhixing.2.31.png and the transparency is 0.5. 
     For blush, the path is makeup/blush/shaonv.2.31.png and the transparency is 0.8. 
     For eyeliner, the path is makeup/eyeliner_292929/wenrou.2.31.png and the transparency is 0.5. 
     For lipstick, the path is makeup/mouth_zirun/zhenggongse.2.31.png and the transparency is 0.5. 
     For highlight, the path is makeup/highlight/highlight.2.12.png and the transparency is 0.4.
*/
}

- (void)testFaceShape
{
    // Enable face shaping.
    // Configure the mode parameter to specify a face shaping mode. Valid values: kQueenBeautyFilterModeFaceShape_Baseline, kQueenBeautyFilterModeFaceShape_Main, 
       kQueenBeautyFilterModeFaceShape_High, and kQueenBeautyFilterModeFaceShape_Max. The values are listed in ascending order by deformation level.
    [self.beautyEngine setQueenBeautyType:kQueenBeautyTypeFaceShape enable:YES mode:kQueenBeautyFilterModeFaceShape_Main];

    // Set the level of big eyes.
    [self.beautyEngine setFaceShape:kQueenBeautyFaceShapeTypeBigEye value:1.0f];
    // Set the level of hairline.
    [self.beautyEngine setFaceShape:kQueenBeautyFaceShapeTypeHairLine value:1.0f];
    // Set the level of smiling.
    [self.beautyEngine setFaceShape:kQueenBeautyFaceShapeTypeSmile value:1.0f];
}

- (void)testBodyShape
{
    // Enable face shaping.
    [self.beautyEngine setQueenBeautyType:kQueenBeautyTypeBodyShape enable:YES];
    // Set the level of leg lengthening.
    [self.beautyEngine setFaceShape:kQueenBeautyBodyShapeTypeLongLag value:1.0f];
    //    // Set the level of head size reduction.
    //    [self.beautyEngine setFaceShape:kQueenBeautyBodyShapeTypeSmallHead value:1.0f];
}

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

    // Specify the filter that you want to use. The path of the resource can be an absolute path.
    [self.beautyEngine setLutImagePath:@"lookups/ly1.png"];
    // Set the level of the filter.
    [self.beautyEngine setQueenBeautyParams:kQueenBeautyParamsLUT value:0.8f];
}

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

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

//    // Enable blue screen for chroma key.
//    enableBlue = YES;
//    [self.beautyEngine setGreenScreen:backgroundImgPath blueScreenEnabled:enableBlue threshold:threshold autoThresholdEnabled:autoThreshold];

//    // Disable chroma key.
//    [self.beautyEngine setGreenScreen:nil blueScreenEnabled:enableBlue threshold:threshold autoThresholdEnabled:autoThreshold];
}

- (void)testBackgroundCutout
{
// Before you enable background replacement, you can specify the performance mode based on your business requirements. The supported performance modes include Auto Mode, Best Quality Mode, Balance Mode, and Best Performance Mode. If you do not configure this parameter, Auto Mode is used by default.
// [self.beautyEngine setSegmentPerformanceMode:kQueenSegmentPMAuto];

//    // Enable background bokeh.
//    [self.beautyEngine setQueenBeautyType:kQueenBeautyTypeBackgroundProcess enable:YES];
//    // After you enable background bokeh, the background is blurred by default. You can use the following API operation to configure a transparent background. This is suitable for scenarios in which the output is used as a foreground and the background is synthesized.
//    [self.beautyEngine setSegmentBackgroundProcessType:kQueenBackgroundTransparent];
//    // Disable background bokeh.
//    [self.beautyEngine setQueenBeautyType:kQueenBeautyTypeBackgroundProcess enable:NO];
//
      NSString *backgroundResPath = @"background/static_changlang";// The path of the resource can be an absolute path.
      // Replace the background with a new static image. A resource cannot be added more than once.
      [self.beautyEngine addMaterialWithPath:backgroundResPath];
//    // Remove the added background image.
//    [self.beautyEngine removeMaterialWithPath:backgroundResPath];
}

- (void)testAutoFilter
{
     // Enable intelligent dynamic optimization.
     [self.beautyEngine setQueenBeautyType:kQueenBeautyTypeAutoFilter enable:YES];
    // Disable intelligent 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 proxy.    self.beautyEngine.delegate = self;
}
- (void)testSportDetect
{
    // Enable movement detection.
    [self.beautyEngine setQueenBeautyType:kQueenBeautyTypeBodyDetect enable:YES];
    // Clear the movement count.
    [self.beautyEngine clearBodySportCount];
    // Set the types of movements that need to be detected and counted. 0 indicates posture recognition, 1 indicates rope jumping, 2 indicates jumping jack, 3 indicates squat, 4 indicates arm circle, 5 indicates diamond stretch, 6 indicates chest stretch, 7 indicates sit-up, 8 indicates push-up, and 9 indicates kneeling push-up.
    [self.beautyEngine setBodyDetectSportType:0];
    //    // Disable movement detection.
    //    [self.beautyEngine setQueenBeautyType:kQueenBeautyTypeBodyDetect enable:NO];

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

- (void)queenEngine:(QueenEngine *)engine didDetectBodyInfo:(QEBodyInfoData *)bodyInfoData
{
    if (bodyInfoData.bodySportType <= 0)
    {
        /*
         {{1, Normal}, // Standing upright.
         {2, HandsUp}, // Raising both hands.
         {3, HandsOnHead}, // Hand heart or touching head.
         {4, LHandUp}, // Raising left hand.
         {5, RHandUp}, // Raising right hand.
         {6, HandLeft}, // Turning left 1.
         {7, HandRight}, // Turning right 1.
         {8, DaShape}, // Arms and legs wide apart.
         {9, HandLeft2},// Turning left 2 with arms akimbo.
         {10, HandRight2},// Turning right 2 with arms akimbo.
         {11, SuperLeft}, // Superman pose towards left.
         {12, SuperRight}, // Superman pose towards right.
         {13, Akimbo}} // Arms akimbo.
         */
        NSLog(@"Posture recognized: %ld", (long)bodyInfoData.bodyPoseType);
    }
    else
    {
        NSLog(@"Movement recognized: %ld. Count: %ld.", (long)bodyInfoData.bodySportType, (long)bodyInfoData.sportCount);
    }
}
- (void)testReHairColor
{
    // Enable hair color try-on.
    [self.beautyEngine setQueenBeautyType:kQueenBeautyTypeHairColor enable:YES];

    // Configure hair color try-on.
    [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 AR-powered in-air writing.
    [self.beautyEngine setARWriting:YES mode:0];
}

- (void)testDebug
{
    // Specify whether to show facial traits for recognition.
    [self.beautyEngine showFaceDetectPoint:YES];
    // Specify whether to show the triangulation information for makeup.
    [self.beautyEngine showMakeupLine:YES];
    // Specify whether to show hand traits for recognition.
   [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; // Specify the rotation angle of the input frame images. Otherwise, facial recognition fails. If you are not sure about the rotation angle of the input frame images, set this parameter in the same manner as you set the cameraRotate parameter.
        bufferData.outputAngle = self.cameraRotate; // Set this parameter to the value of the inputAngle parameter.
#endif
        // Process the input frame images and export the processed frame images.
        kQueenResultCode resultCode = [self.beautyEngine processPixelBuffer:bufferData];// Use the same thread to execute this method.
        if (resultCode == kQueenResultCodeOK && bufferData.bufferOut)
        {
            return bufferData.bufferOut;
        }
        else if (resultCode == kQueenResultCodeInvalidLicense)
        {
            NSLog(@"License authentication failed.");
        }
        else if (resultCode == kQueenResultCodeInvalidParam)
        {
            NSLog(@"The parameter is invalid.");
        }
        else if (resultCode == kQueenResultCodeNoEffect)
        {
            NSLog(@"No effects are enabled.");
        }
        return pixelBufferRef;
        }
    else
       {
        return pixelBufferRef;
       }
}

- (void)captureReset
    {
    if (self.beautyEngine)
    {
        // Release QueenEngine. Make sure that the current thread is the same as the thread that is used to execute 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: %ld, Movement type: %d", (long)gestureData.gesture, gestureData.action);
}

Sample code for data and texture segmentation

/**
The callback for textures processed by QueenEngine.
*/
- (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.beautyEngine processTexture:textureData];
        if (result != kQueenResultCodeOK) {
            NSLog(@"queen beauty processTexture error. code: %lu", result);
        }
        return textureData.outputTextureID;
    }
    return texture;
}

/**
The callback for detections processed by QueenEngine.
*/
- (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;
}

/**
The callback for destroying QueenEngine.
*/
- (void)onDestory
{
    if (nil != self.beautyEngine) {
        [self.beautyEngine destroyEngine];
        self.beautyEngine = nil;
    }
}