Perfectly Clear SDK Documentation
Docker Container
Perfectly Clear Docker Container
Perfectly Clear Docker Container

This document will explain how to get our Docker container up and running, how to configure it, and how to use the logging facility to diagnose any issues you might encounter.

The container will mount two volumes - one containing presets to use when applying Perfectly Clear, and a second containing your SDK license key.

Once the container is running, you will interact with it via a HTTP API, through the process:

  1. Upload a JPEG or PNG image to be corrected using the PUT method. The API will return an imageKey.
  2. Call the GET method with the imageKey of the image you want to correct. Optionally, provide the name of the Preset to apply when correcting the image, and the type of image you want (JPG or PNG) or image resizing parameters. The GET method with return the URL of the corrected image and resizing parameters.
  3. Download the corrected image and use in your applications. The original and corrected images will be stored for at least 12 hours, and no more that 24 hours. If you need the corrected image again after this time, you'll need to re-upload and re-correct it.

Table of Contents

  1. Requirements
  2. API Interface
    1. Upload
    2. Correction
    3. Version
  3. About Resizing Parameters
  4. Examples
  5. Configuration
    1. Presets
    2. License Key
    3. Server Configuration
  6. Logging
  7. FAQ & Trouble Shooting


Docker is required to run the container.

The following packages are required by the sample "" script.

  • curl
  • jq

These can typically be installed with sudo apt-get install jq curl on newer linux distributions.

API Interface

You will interact with this container using an HTTP API interface. It is exactly the same API that our public Web API uses - the only difference is the URL endpoint.

PUT /pfc

Upload original image to make it ready for corrections


Name Description
Content-Type Required. Either 'image/jpeg' or 'image/png'

Request body

JPEG or PNG Image


Code Description
200 Success

Content: application/json

    "imageKey": "string"
400 Header Content-Type not found.
503 Internal server error.

GET /pfc/{imageKey}

Apply Perfectly Clear image correction and get the URL to download the corrected image.


Name Description
Required. ID of uploaded image, as returned from the PUT method
Optional. Name of your preset. Mount presets to the /presets folder. Default = Intelligent Auto
Optional. Either 'JPEG' or 'PNG' - used to set the type of file returned. Default = same as input file.
width, height, long, short
Optional. Chosen dimension of the output image in pixels. Capped to 100,000px.
Optional. Scale of the image in percentage points. Capped to 100,000%.
Optional. Sets the quality of the output image. Only accepted for JPEG and ignored for any other output types. Defaults to 90. Must be between 40 and 100.


Code Description
200 Success

Content: application/json

    "corrected_url": "string"
400 Unknown or invalid image key.
503 Internal server error.

GET /version

Get a report on the Perfectly Clear SDK version


Code Description
200 Text report of the Perfectly Clear SDK version and features supported

About Resizing Parameters

When resizing, only one parameter is used even if multiple parameters are provided. Non-integer paramerer are ignored. The order of priority is:

  1. width
  2. height
  3. long
  4. short
  5. scale

Width and Height will set the output size to have either the specified width or height - which ever is specified. The other dimension will be automatically determined to maintain the same aspect ratio as the original image.

Long and Short will set the output size based on the long or short side - which ever is specified. The other dimension will be automatically determined to maintain the same aspect ratio as the original image.

When using the scale parameter, the value should be an integer represenation of the percent scale you would like to apply. For example, scale=50 would be a 50% scale, or half the width and half the height of the original image.

Example Script

We have provided a simple script to demonstrate the API. You can run make in this folder to load the docker image, run the container, and upload, correct and download a sample JPEG image.

The manual steps are:

  1. Verify that your license files are the sdk_license folder.

  2. Add the docker image to your docker engine:

    docker load --input pfc_container_image.tar

  3. Run the imported image:

    docker run -it -v "$(shell pwd)/presets":/presets -v "$(shell pwd)/sdk_license":/sdk_license \
    	-p 80:80 -e PFC_LOG_LEVEL='debug' pfc_container

The container is now running attached and in debug mode to inspect everything is properly setup. It has mounted the presets directory to /presets and the sdk_license folder to /sdk_license.

  1. Upload an image and parse and save the imageKey:

    imageKey=$(curl -H "Content-Type: image/jpeg" -X PUT "http://localhost:80/pfc" --upload-file sample.jpg | jq -r '.imageKey')

  2. Correct the image with the default preset:

    correctedImageUrl=$(curl -v -X GET "http://localhost:80/pfc/${imageKey}?preset=auto" | jq -r '.corrected_url')

  3. Download the finished image:

    curl "${correctedImageUrl}" -o corrected.jpg

There are two other scripts included in this package - and These are very similar to the script, but show the process to convert from JPG to PNG and also to apply image resizing.


There are three ways to configure and influence how this docker solution operates.


The container does not contain any presets by default. It expects them to be mounted under /presets. You can export presets from any of our desktop applications to individual .preset files. Copy these files to the mounted /presets volume to make these available for use, by name, by the correction API.

SDK License

Copy the sdk_license files provided to you by EyeQ to the local sdk_license folder, then mount it under /sdk_license.

Server configuration with environment variables

The following environment variables will affect the behavior of the application. These can be set when calling the docker run command, for example with: -e PFC_LOG_LEVEL='debug'.

PFC_SITE_URL Set the URL to direct the clients to download the Image from. Defaults to http://localhost
PFC_USE_FASTFAE The face aware exposure algorithm has a fast but less accurate setting that can be toggled on using the PFC_USE_FASTFAE setting. Defaults to "false".
PFC_AVX The container can make use of AVX instruction set to improve performance, if available. Set PFC_AVX to "on", "off" or "auto" (default) which detects if AVX is available and uses it.
PFC_LOG_LEVEL Sets the logging level to one of: debug, info, warning, error. Defaults to "info".

Listen address: the server inside the container listens to


The server uses the logrus logger package As such it supports the same logger levels under the environment variable PFC_LOG_LEVEL. It defaults to info.

It's configured to use json formating for easy parsing in case it's needed. They can be easily read through docker logs pfc_container.


Server side logs divide into 4 different severity levels:

  • Debug: for information useful while first deploying, it's used to log an incoming request and its procesing even if no errors occur. Also show user error.
  • Info: default logging level - reports basic usage information
  • Warning: might be a problem but doesn't need immediate attention.
  • Error: you should be aware of this. Used for states that cannot be solved through code and need manual intervention.
Id Level Method Message Causes Possible solution User facing HTTP error
configuredMessage Error Configured Always shown to display paramaters
unknownErrorLevelMessage Error Unknown log level. Defaulting to 'info' Not recogniced error level Use a valid error level: 'Debug', 'Info', 'Warning', 'Error' (case insensitive)
noContentTypeRequestMessage Debug PUT /pfc/ Ignoring request with wrong Content-Type An user sent a request with an unsuported header 400
bodyRequestMessage Error PUT /pfc/ Couldn't read body request The request image itself couldn't be extracted Probably wrongly encoded by the user or too much RAM pressure on your container 503
temporaryFileCreationMessage Error PUT /pfc/ Couldn't create temporary file for input image Make sure /input inside the container is writable and the machine has enough HDD 503
temporaryFileWritingMessage Error PUT /pfc/ Couldn't close temporary file for output Make sure /input inside the container is writable and the machine has enough HDD 503
savingImageMessage Debug PUT /pfc/ Processing image An image was processed
noIdMessage Debug GET /pfc/{id} Ignoring request without image key Client called GET on /pfc/ Correct client code 400
invalidIdMessage Debug GET /pfc/{id} Ignoring invalid imageKey Sanity check for ID failed Use correct image ID 400
unknownImageIdMessage Debug GET /pfc/{id} Ignoring request with unknown image key The given ID does not exist Use correct image ID 400
unknownPresetMessage Debug GET /pfc/{id} Unknown preset requested The preset has not been uploaded or mounted Make sure to mount the correct preset directory under /presets and the preset is there or correct the calling code 400
temporaryOutputFileMessage Error GET /pfc/{id} Couldn't create temporary file for output The /output partition is full or not writable Make sure the volume or machine has enough capacity or permissions. See exact error under 'error' 503
temporaryCloseOutputFileMessage Error GET /pfc/{id} Couldn't close temporary file for output The /output partition is full or not writable Make sure the volume or machine has enough capacity or permissions. See exact error under 'error' 503
correctingImageMessage Debug GET /pfc/{id} Processing image
processingPFCErrorMessage Error GET /pfc/{id} PerfectlyClear processing failed Processing of the image caused errors check further details under 'error'. Some specific images causes the corrections to fail and cannot be corrected through PFC. 503
cleanUpFileMessage Info Couldn't delete file Couldn't delete an image from the /input or /output directories If mounting them make sure the proper permissions are set
unknownOutputTypeMessage Debug Unknown output file type requested Only JPEG (or jpg) or PNG are supported Change the client to only ask for JPEG or PNG
versionMessage Info GET /version Displays Perfectly Clear SDK version

FAQ & Trouble Shooting

  • The corrected image appears identical to the original image. This is typically due to a failed license verification. Check that the sdk_license folder exists and contains your license key.

  • I get "couldn't write image" error. This could be because Docker ran out of disk spcace or you reached a quota of docker.

  • My small image is rejected. Perfectly clear needs images of at least 32px on its short side.

  • Some Beautify corrections aren't applied. Beautify corrections are disabled on images of aspect ratios higher than 21:1.