# Configure Drawing with a Lua Script

The `Draw` transformation task draws regions on images or video frames. This section demonstrates how to customize the regions that are drawn by using a Lua script.

The Lua script that you write must define a function with the name `draw`. The function is passed each record from the input track. For example, the following function draws an ellipse on each record from the `ResultWithSource` track produced by face detection:

    function draw(record)
       drawEllipse(record.FaceResultAndImage.face.ellipse, 3, rgb(255,255,255))
    end

For information about the Lua functions that you can use to draw regions on images and video frames, refer to the Media Server Reference.

To configure drawing with a Lua script

1. Create a new configuration to send to Media Server with the `process` action, or open an existing configuration that you want to modify.

2. In the `[Session]` section, add a new task by setting the `EngineN` parameter. You can give the task any name, for example:

       [Session]
       Engine0=Ingest
       ...
       Engine3=Draw

3. Create a new configuration section to contain the task settings and set the following parameters:

   `Type` | The transformation engine to use. Set this parameter to `Draw`.
   `Input` | The name of the track that contains the images to draw on, with region data. The track must supply records that contain both an image and at least one region.
   `LuaScript` | The path of a Lua script to run to draw on the source images or video frames.

   For example:

       [Draw]
       Type=Draw
       Input=Demographics.ResultWithSource
       LuaScript=lua/drawDemographics.lua

4. Save and close the configuration file. Micro Focus recommends that you save your configuration files in the location specified by the `ConfigDirectory` parameter.

Example configuration to draw regions on encoded images using a Lua script

An example configuration file, `configurations/examples/Other/Draw_Faces.cfg`, is included in your Media Server installation.

The following example runs face detection and demographics analysis on a video file or stream. It encodes images of the detected faces, using a Lua script to outline male faces in orange and female faces in purple.

    [Session]
    Engine0=Ingest
    Engine1=FaceDetect
    Engine2=Demographics
    Engine3=Draw
    Engine4=Images

    [Ingest]
    Type=Video

    [FaceDetect]
    Type=FaceDetect
    NumParallel=6
    MinSize=10%

    [Demographics]
    Type=Demographics
    Input=FaceDetect.ResultWithSource
    NumParallel=2

    [Draw]
    Type=Draw
    Input=Demographics.ResultWithSource
    LuaScript=drawDemographics.lua

    [Images]
    Type=ImageEncoder
    ImageInput=Draw.Output
    OutputPath=./output/%session.token%/%record.starttime.iso8601%.png

The Lua script `drawDemographics.lua` is included below:

    function draw(record)
      local result = record.DemographicsResultAndImage

      if ('Male' == result.gender) then
        -- draw orange ellipse
        drawEllipse(result.face.ellipse, 5, rgb(255, 128, 0))

      elseif ('Female' == result.gender) then
        -- draw purple ellipse
        drawEllipse(result.face.ellipse, 5, rgb(64, 0, 128))

      else
        -- draw grey ellipse
        drawEllipse(result.face.ellipse, 5, rgb(128, 128, 128))

      end
    end

Example Lua script to process combined/nested records

To draw outlines around multiple types of region, for example both detected faces and recognized logos, you can combine multiple tracks using a combine ESP task. The output from the combine ESP task, and the input for the drawing task, is therefore a track where records contain other records. In this case, your Lua script must process the nested records. The following script demonstrates how to do this:

    function dispatchResult(record)
    	-- handle the single records here
    end

    function uncombine(record)
    	if (record.CombineOperationData) then
    		local i = 1
    		while (record.CombineOperationData.combinedRecords[i]) do
    			uncombine(record.CombineOperationData.combinedRecords[i])
    			i = i + 1
    		end
    		uncombine(record.CombineOperationData.record0)
    	else
    		dispatchResult(record)
    	end
    end

    function draw(record)
    	uncombine(record)
    end

_FT_HTML5_bannerTitle.htm