Perfectly Clear SDK Documentation  8.3.1.149
Correction Parameters

Corrections in this SDK

The image corrections available include:

  1. Perfectly Clear Core Corrections
  2. Noise Corrections
  3. Red-eye removal
  4. "Beautify" Corrections (licensed as an optional component)
  5. "V3 Looks" support - Finishing and Graduated Filters, along with several other corrections added in the "V3" versions of our Desktop products. These include:
    1. Color Vibrancy
    2. Neutral Density
    3. Foliage and Sky Enhancement
    4. Input Corrective Filters
    5. Output LOOKs
    6. Finishing Tools
    7. Graduated Filters

V3 LOOKs support is not available at this time on mobile platforms, and is provided via an optional "v3.looks" file. The supported LOOKs are listed here

These various corrections are best previewed and evaluated in our desktop applications like Perfectly Clear Complete or QuickDesk.

Setting Correction parameters

There are three ways you can set the correction parameters to be applied in this SDK:

  1. Use one of the pre-defined presets available in the PFCPRESETID enum
  2. Read a .preset file exported from any Perfectly Clear desktop application using PFC_ReadPresets
  3. Manually define all the various parameters in the PFCPARAM struct, which is usually done by copy/pasting code from the 'Export to API' function in our business-related desktop applications.

Let's look at each of these in a little more detail.

1. Using pre-defined presets

The quickest way to get started with this SDK is to use one of our built-in presets to populate the PFCPARAM struct that you'll need when calling PFC_Apply or PFC_AutoCorrect. This is as simple as:

// Declaration of PFCPARAM.
PFCPARAM param;
// Initialize process parameters. If presetID is left blank, default to using Intelligent Auto preset.
PFC_SetParam(param, PRESET_INTELLIGENTAUTO);

Now, the param struct is populated with all the various correction parameters defined with our Intelligent Auto preset. This preset has been carefully designed with years of feedback from our customers, and is used on millions of photos per day. If you want to make a few changes to these parameters, you can set individual parameters:

param.core.bDCF=true;
param.core.eDCFMode=DCF_VIVID;

2. Reading .preset files

All our desktop applications can export presets to XML files which will end in the .preset file extension. These files can then easily be read using PFC_ReadPresets like this:

PFCPARAM param;
char* profilename = "/path/to/approved_parameters.preset";
int ret = PFC_ReadPresets(param, profilename);

Now, the param struct is populated with all the various correction parameters defined with the settings you created in the file /path/to/approved_parameters.preset . Here's a link to the User Guide of Perfectly Clear that explains how to export these .preset files: https://www.athentech.com/help/plugins/PerfectlyClearComplete-v3/index.html?about_the_perfectly_clear_interface.html

This is the quickest way for you to get your custom parameters in use with this SDK.

3. Copy / Pasting Parameter Code

Lastly, you can export the standard C or C# code from Perfectly Clear Complete (with a special 'Workbench' license code) or QuickDesk. Notes on how to do that are here: https://www.athentech.com/help/plugins/PerfectlyClearWorkbench-v3/what-is-workbench_.html

Once you have this exported text file, open it up and you will see various sections for C or C# syntax. Within these major sections, you will find the various parameters for each of the PFCPARAM groups: PFCCOREPARAM, PFCNRPARAM, PFCREPARAM, PFCFBPARAM, and PFCV3PARAM, including layers and masks.

For example, here is the full C code required to set all the parameters for our Intelligent Auto preset (see below). All of the PFCV3PARAM sections are empty or zero value, so these can safely be omitted.

This method allows you to hard-code specific parameters into the applications you compile with this SDK. This can be useful to prevent accidental changes to the parameters, which would be possible if they were being read from an external .presets file.

If your application allows the end-user to change parameters, then this method also allows you change individual parameter programmatically.

param.core.bEnabled=true;
param.core.bAbnormalTintRemoval=false;
param.core.eTintMode=TINTCORRECT_STRONGEST;
param.core.fTintScale=0.50f;
param.core.bVibrancy=true;
param.core.iVibrancy=0;
param.core.bUseAutomaticStrengthSelection=true;
param.core.eAggressiveness=AGGRESSIVENESS_MODERATE;
param.core.iMaxStrength=100;
param.core.iStrength=0;
param.core.bContrast=true;
param.core.iContrast=93;
param.core.eContrastMode=HIGH_DEFINITION;
param.core.iBlackEnhancement=12;
param.core.eBiasMode=BIAS_AVERAGE_PREFERENCE;
param.core.fBiasScale=0.30f;
param.core.bSharpen=true;
param.core.fSharpenScale=0.60f;
param.core.bInfrared=true;
param.core.fInfrared=0.75f;
param.core.bDCF=false;
param.core.eDCFMode=DCF_STANDARD;
param.core.fDCF=0.50f;
param.core.bLightDiffusion=false;
param.core.fLightDiffusion=0.50f;
param.core.bUseFAE=true;
param.core.bDynamicRange=true;
//PFCNRPARAM
param.nr.bEnabled=false;
param.nr.iPreset=0;
param.nr.iStrengthOffset=0;
param.nr.iDetailOffset=0;
//PFCREPARAM
param.re.bEnabled=true;
//PFCFBPARAM
param.fb.bEnabled=true;
param.fb.bSmooth=true;
param.fb.iSmoothLevel=36;
param.fb.eSmoothMode=SKINMODE_FACE;
param.fb.eSmoothType=SKINSMOOTHTYPE_SUBTLE;
param.fb.bEnlarge=false;
param.fb.iEnlargeLevel=0;
param.fb.bEnhance=true;
param.fb.iEnhanceLevel=50;
param.fb.bEyeCirc=true;
param.fb.iEyeCirc=28;
param.fb.bTeeth=false;
param.fb.iTeethLevel=0;
param.fb.bBlemish=false;
param.fb.iBlemish=0;
param.fb.bSlim=false;
param.fb.iSlim=0;
param.fb.bDeFlash=true;
param.fb.iDeFlash=8;
param.fb.bCatchLight=false;
param.fb.iCatchLight=0;
param.fb.iCatchLightMode=1;
param.fb.bSkinToning=false;
param.fb.iSkinToning=0;
param.fb.eSkinToningMode=SKINMODE_FACE;
param.fb.eSkinToningType=SKINTONINGTYPE_PALE;
param.fb.bLipSharpen=false;
param.fb.iLipSharpen=0;
param.fb.eLipSharpenType=LIPSHARPENTYPE_FINE;
param.fb.bBlush=false;
param.fb.iBlush=0;
//PCC V3 ADDITIONS
param.v3.bPreprocessEV=false;
param.v3.iPreprocessEV=0;
param.v3.iNeutralDensity=0;
param.v3.iColorVibrancy=0;
strcpy(param.v3.lutInputCorrective.guid,"00000000000000000000000000000000");
param.v3.lutInputCorrective.strength=0;
strcpy(param.v3.lutInputSky.guid,"00000000000000000000000000000000");
param.v3.lutInputSky.strength=0;
strcpy(param.v3.lutInputFoliageGreen.guid,"00000000000000000000000000000000");
param.v3.lutInputFoliageGreen.strength=0;
strcpy(param.v3.lutInputFoliageBrown.guid,"00000000000000000000000000000000");
param.v3.lutInputFoliageBrown.strength=0;
strcpy(param.v3.lutOutput.guid,"00000000000000000000000000000000");
param.v3.lutOutput.strength=0;
//This layer is DISABLED. Ignore this set of params if you wish
param.layer[0].iFinishTemp=0;
param.layer[0].iFinishTint=0;
param.layer[0].iFinishExposure=0;
param.layer[0].iFinishBlacks=0;
param.layer[0].iFinishShadows=0;
param.layer[0].iFinishHighlights=0;
param.layer[0].iFinishWhites=0;
param.layer[0].iFinishSaturation=0;
param.layer[0].iFinishVibrancy=0;
param.layer[0].iFinishContrast=0;
strcpy(param.layer[0].lutInputSky.guid,"00000000000000000000000000000000");
param.layer[0].lutInputSky.strength=0;
strcpy(param.layer[0].lutInputFoliageGreen.guid,"00000000000000000000000000000000");
param.layer[0].lutInputFoliageGreen.strength=0;
strcpy(param.layer[0].lutInputFoliageBrown.guid,"00000000000000000000000000000000");
param.layer[0].lutInputFoliageBrown.strength=0;
param.mask[0].type=MASK_NONE;
param.mask[0].centerX=0.50000000f;
param.mask[0].centerY=0.50000000f;
param.mask[0].width=1.17910051f;
param.mask[0].height=1.17910051f;
param.mask[0].radius=0.00000000f;
param.mask[0].feather=0.80000001f;
param.mask[0].angle=0.00000000f;
param.mask[0].transparency=0.00000000f;
param.mask[0].invert=false;
//This layer is DISABLED. Ignore this set of params if you wish
param.layer[1].iFinishTemp=0;
param.layer[1].iFinishTint=0;
param.layer[1].iFinishExposure=0;
param.layer[1].iFinishBlacks=0;
param.layer[1].iFinishShadows=0;
param.layer[1].iFinishHighlights=15;
param.layer[1].iFinishWhites=0;
param.layer[1].iFinishSaturation=-20;
param.layer[1].iFinishVibrancy=0;
param.layer[1].iFinishContrast=-25;
strcpy(param.layer[1].lutInputSky.guid,"00000000000000000000000000000000");
param.layer[1].lutInputSky.strength=0;
strcpy(param.layer[1].lutInputFoliageGreen.guid,"00000000000000000000000000000000");
param.layer[1].lutInputFoliageGreen.strength=0;
strcpy(param.layer[1].lutInputFoliageBrown.guid,"00000000000000000000000000000000");
param.layer[1].lutInputFoliageBrown.strength=0;
param.mask[1].type=MASK_NONE;
param.mask[1].centerX=0.50000000f;
param.mask[1].centerY=0.50000000f;
param.mask[1].width=1.17910051f;
param.mask[1].height=1.17910051f;
param.mask[1].radius=0.00000000f;
param.mask[1].feather=0.80000001f;
param.mask[1].angle=0.00000000f;
param.mask[1].transparency=0.00000000f;
param.mask[1].invert=true;
//This layer is DISABLED. Ignore this set of params if you wish
param.layer[2].iFinishTemp=0;
param.layer[2].iFinishTint=0;
param.layer[2].iFinishExposure=0;
param.layer[2].iFinishBlacks=0;
param.layer[2].iFinishShadows=0;
param.layer[2].iFinishHighlights=0;
param.layer[2].iFinishWhites=0;
param.layer[2].iFinishSaturation=0;
param.layer[2].iFinishVibrancy=0;
param.layer[2].iFinishContrast=0;
param.mask[2].type=MASK_NONE;
param.mask[2].centerX=0.50000000f;
param.mask[2].centerY=0.50000000f;
param.mask[2].width=0.00000000f;
param.mask[2].height=0.00000000f;
param.mask[2].radius=0.00000000f;
param.mask[2].feather=0.50000000f;
param.mask[2].angle=0.00000000f;
param.mask[2].transparency=0.00000000f;
param.mask[2].invert=false;