1. Image JSON and Rendering – Function Reference

This documentation page is valid for ACF-Plugin version 1.7.8.7, available in the download area.

All image functions work in two phases:

  1. Build a JSON definition

    • NewImage creates a JSON object describing an image (type, width, height, background, etc.).
    • All Image… commands take this JSON variable as first parameter and append commands to img["commands"].
    • Most commands have Styleoptions as last parameter. We have used the JSON function in the ACF-language to create those. The JSON function creates a JSON object from a "key/value" parameter list, where all odd parameter numbers are keys, and even parameter numbers are values. A value can be another JSON function or JSONarray function to make nested JSON levels. You can also define commonly used options as separate JSON variables, and use them instead of defining the options for each command.
  2. Render the image

    • SaveImage renders the JSON definition to a file.
    • GetImage renders to a binary string (e.g. for storing in a container).

The first parameter for all commands (except NewImage) must be a JSON variable created by NewImage.

About the datatypes given in the syntax-section: "number" is not an ACF datatype, but is a collective description where it accepts both int, long and float types.


  1. Image JSON and Rendering – Function Reference
    1. NewImage
    2. ImageAddImage
    3. ImageCircle
    4. ImageArc
    5. ImagePieSegment
    6. ImagePolygon
    7. ImageStar
    8. ImageClosedPath
    9. ImageSquare
    10. ImageRect
    11. ImageAddBarcode
    12. ImageLine
    13. ImageDrawText
    14. ImageDrawTextBox
    15. ImageAddText
    16. ImageCornerBanner
    17. ImageSetLineStyle
    18. ImageSetFont
    19. ImageAppend
    20. SaveImage
    21. GetImage
  2. Examples
    1. Business card
    2. Packing label

1.1. NewImage

difference-inksape-font-versus-drawtextbox

function TestSVGfonts ()

    string svg = desktop_directory() + "/Skrifter.svg"; 
    float width = 210/25.4*300; 
    float height = 148/25.4*300;
    JSON img = NewImage (width, height, JSON("color", "white", "image", ":svg", "dpi", 300)); 

    ImageDrawTextBox (img, width/2, height/3*2, width*2/6, height/4, 
        "Dette er en liten text med masse info. Jeg ser hvordan denne tar seg ut i bildet med hensyn på kerning, og flyt (DrawTextBox)", 
        JSON ("font", JSON ("name", "helvetica", "style", "thin", "size", 35, "color", "blue"))); 
    string outPath = desktop_directory() + "/skrifter-output.png"; 
    SaveImage ( img, outPath );
    return string (img); 
end

1.2. ImageAddImage

Example:

ImageAddImage (img, 30, 30, width/2*0.9-30, 200, ":logo");

1.3. ImageCircle


1.4. ImageArc


1.5. ImagePieSegment


1.6. ImagePolygon


1.7. ImageStar

Example:

// Star
    ImageStar (img, 150, 400, 70, 130, 12, json(
            "fill", json ("color", "red", "alpha", 1.0),
            "line", json ("color", "black")) ); 

star


1.8. ImageClosedPath

Example:

ImageClosedPath(
      img, 0, height/2,
      JSON(
        "segments", JSONarray(
          JSON("type", "line", "to", JSONarray(width*0.3, height/2)),
          JSON("type", "arc", "to", JSONarray(width/2, height*0.7), "angle", 60),
          JSON("type", "arc", "to", JSONarray(width*0.75, height*0.90), "angle", -60),
          JSON("type", "line", "to", JSONarray(width, height*0.90, width, height, 0, height))
        ),
        "style", JSON(
          "fill", JSON("type", "gradient", "color", "blue", "color2", "green", "alpha", 0.45, "direction", 135)
        )
      )
    );

mytestimagex


1.9. ImageSquare


1.10. ImageRect

Key Description Default value

1.11. ImageAddBarcode

This is used for generating barcodes or QR codes on the image. We use the Zint barcode library for this having more than 100 barcode formats, including QR code. See the example near the bottom of the page to see how it looks like.

Key Description Default value
type Name of barcode type from the barcode table. (Ex. qr, ean13, etc), See Barcode table No default
fgColor Foreground color (pixels) (named color or 6 digit value or color-object) Style guide Black
bgColor Background color (named color or 6 digit hex value or color-object) Style guide White
ecLevel ECC level (L=20%, M=37%, Q=55%, H=65%) M
border Integer, Zint border size (default 4), an Object descibing borders, or an array containing multiple border defenitions. No border
rotate Rotation degrees. Positive values are CW, - neg values are CCW 0
scale Scaling of the barcode, integer number as scale factor 1
drawtext Boolean value whether to draw text (numbers) below the symbol or not. The numbers are drawn using a built-in OCRB-13 raster font. If you want better quality you can select false here, and draw the text using imageDrawTextBox just below the symbol. For this approach the selected font must be installed in the system (Fontbook on MacOS). true

Example:

function testQR()
    JSON img = NewImage ( 300, 300, JSON("color", "white") );

    JSON styleQR = JSON ( "type", "QR",
                          "fgColor", "teal",
                          "bgColor", "white",
                          "ecLevel", "M",
                          "rotate", 0 );

    ImageAddBarcode ( img,
                      50, 50, 200, 200,
                      "https://horneks.no/",
                      styleQR );

    string path = desktop_directory() + "/barcode_test.png";
    SaveImage ( img, path );
    return string(img); 
end

barcode_test


1.12. ImageLine


1.13. ImageDrawText


1.14. ImageDrawTextBox

Example:

ImageDrawTextBox (img, 100, 100, 150, 150,
        "This is a little text box with some long text in it, to see how it splits", 
        JSON("align", "right", "color", "white", "alpha", 0.30, "size", 18, 
            "border", JSONarray(
            JSON("width", 10, "color", "white"), 
            JSON("width", 1, "color", "black"))));

1.15. ImageAddText

Example:

  JSON font1 = json ("name", "Helvetica", "color", "black", "size", 24, 
        "style", JSONarray("bold"));

    imageSetFont(img, font1); 
    ImageDrawTextBox ( img, boxLeft, height/2, boxwidth, height/2, name, 
        JSON ("align", "center", "size", 20, "alpha", 0.0));
    
    font1["style"] = JSONarray("italic"); 
    font1["size"] = 18; 
    imageSetFont(img, font1); 
    ImageAddText(img, _(position) );  

Skjermbilde 2025-11-14 kl. 19.16.27


1.16. ImageCornerBanner

Example:

// Test corner banners
    JSON box = JSON ("size", 24, "color", "red", "valign", "middle"); 
    ImageCornerBanner ( img, 50, 55, "tr", "SPECIAL\nOFFER", box); 
    ImageCornerBanner ( img, 50, 55, "tl", "**TODAY:**", box); 
    ImageCornerBanner ( img, 50, 55, "bl", "ACT NOW!!", box);
    ImageCornerBanner ( img, 50, 55, "br", "BIG SALE !!", box);

mytestimage


1.17. ImageSetLineStyle


1.18. ImageSetFont


1.19. ImageAppend

Example:

// Helper function:
function MakePieChart (int ext, float x, float y)

    JSON img; 
    int i; 
    int startA = -90; 
    array float depsum = {30000, 4000, 50000, 16000, 100000, 25000}; 
    float gsum = 0; 
    for (i=1,6) gsum += depsum[i]; end for
    float thisAngle;  
    array string colors = {"red", "green", "blue", "grey" ,"yellow", "black"};
    for (i=1,6)
        thisangle = round(depsum[i]/gsum*360,0); 
        ImagePieSegment(img, x, y, 100, 0, startA, thisangle, json(
            "fill", json ("color", colors[i]),
            "line", json ("color", "grey"),
            "extend", ((i==ext)?20:0)); 
        startA += thisangle; 
    end for
    return img; 
end

// And then in the function using it: 
// Pie chart
    ImageAppend(img, MakePieChart(1, 400, 400)); 

1.20. SaveImage


1.21. GetImage

2. Examples

2.1. Business card

In this example I have used InkScape to create a closed path for the bottom of the card. This is used as the background as an SVG image. The logo and a picture are containers on the layout. This method could be useful to produce business cards for all employees based on an employee database.

function cmtoPix300 ( float cm)
    return cm / 2.54 * 300.0; 
end

function BusinessCard ( container logo, container picture, 
        string name, string position, 
        string mobile, string email)

    float width = cmtoPix300(8.5); 
    float height = cmtoPix300(5.5);
    
    string svgpath = desktop_directory() + "/card-test-background.svg";

    JSON img = NewImage (width, height, JSON("image", svgpath, "alpha", 0.35, "dpi", 300));
  // company logo
  ImageAddImage (img, 30, 30, width/2*0.9-30, 200, ":logo");
    // Vertical line
    ImageLine(img, width/2, 30, width/2, height-30); 
    // Employee photo
    float picCenter = width*0.75; 
    float picwidth = width/6.0; 
    ImageAddImage (img, picCenter-picwidth/2 , 50, picwidth, 400, ":picture", json("rotate", -30));

    // Name and Position
    float boxLeft = width / 2 + 30; 
    float boxwidth = (width - 30) - boxLeft; 

    JSON font1 = json ("name", "Helvetica", "color", "black", "size", 24, 
        "style", JSONarray("bold"));

    imageSetFont(img, font1); 
    ImageDrawTextBox ( img, boxLeft, height/2, boxwidth, height/2, name, 
        JSON ("align", "center", "size", 20, "alpha", 0.0));
    
    font1["style"] = JSONarray("italic"); 
    font1["size"] = 18; 
    imageSetFont(img, font1); 
    ImageAddText(img, _(position) ); 
    // 
    imageSetFont(img, json ("name", "Helvetica", "color", "black", "size", 18, 
        "style", JSONarray("normal"))); 
    ImageAddText(img, " " ); 
    ImageAddText(img, char(128241) + " Mob: " + mobile ); 
    ImageAddText(img, char(128231) + " Email: " + email ); 
    
    // Left part, address, info
    ImageDrawTextBox ( img, 30, 160, boxwidth, height/2, 
        "Vollebergveien 18A", JSON ("align", "left", "size", 24, "alpha", 0.0));
    ImageAddText ( img, "1621 GRESSVIK • NORWAY" );
    imageSetFont(img, json ("name", "Helvetica", "color", "black", "size", 24, 
        "style", JSONarray("bold"))); 

    ImageDrawTextBox ( img, 30, height*0.6, boxwidth+30, height/0.4, 
        _("ERP and Business Systems Specialist"), JSON ("align", "left", "size", 24, "alpha", 0.0));

    imageSetFont(img, json ("name", "Helvetica", "color", "black", "size", 22, 
        "style", JSONarray("italic"))); 

    ImageAddText(img,
"• **FileMaker** • 4D • C++ • SQL • PHP • AI
• ACF-Plugin for FileMaker 
• DDRparser

- 40 years of experience in the IT industry"); 

    string path = desktop_directory() + "/testcard-ole2.png"; 
    SaveImage (img, path); 

    return string(img); 
end

Here is the generated card:

testcard-ole2


2.2. Packing label

Here is an example of producing a postal packaging label (The one we use in Norway) - Produced as a PNG image file that can be spooled directly to the label printer. The label is quite detailed with a lot of different font sizes, icons and a bar-code in the bottom.

packlabel

Here is the example code:

We have declared demo data as local variables in the function for this demo, but in a real application this will either be transferred as parameters to the function, or use some SQL to pull them directly from the database.

First a small helper function to convert measurements in mm, to actual pixel units. The image is produced in 300dp resolution.

float dpi, units; 

function u_ (float mm)
    return mm / units / 2.54 * dpi; 
end
function test_PackagingLabel ()

// Some demo data - Use SQL or parameters for real usage. 
    string from = "**From:**\nHORNEKS ANS\nVollebergveien 18A\nNO-1621 GRESSVIK\nNORWAY";

    string ToName     = "Rachel Green"; 
    string ToAddr     = "Trosterudveien 22"; 
    string ToZip      = "NO-9813"; 
    string ToCity     = "FAR NORTH"; 
    string ToPhone    = "+4798765432"; 
    string ToCountry  = "NORWAY"; 

    string LicensePlate   = "370722152138915530"; 
    string Consignment    = "70722152140118935";
    int    packages       = 1, PackageCount = 1; 
    float  weightKg       = 10.0; 
    float  Volume         = 432.0; 
    string PostalCustomerNo = "0"*7 + "2014"; 
    string TransportInstr = "\n\n\nIf Nobody home: Place package inside the front door. \n**Don't let the dog out.**"; 

    // --- Base image setup ---
    dpi   = 300; 
    units = 10; 
    float w = u_(84), h = u_(155); 
    float lm = u_(4); 

    JSON img = NewImage (
        w, h,
        JSON("color", "white", "alpha", 1, "dpi", dpi)
    ); 

    // --- Common styles (JSON) --------------------------------------

    // Generic “no fill, just text” box
    JSON styleTextBase       = JSON("name", "Helvetica","fill", "none", "alpha", 0.0);
    JSON styleTextBaseFat       = JSON("name", "Helvetica Fet","fill", "none", "alpha", 0.0);

    // Small normal text
    JSON styleTextSmall      = JSON("fill", "none", "alpha", 0.0, "size", 24);

    // Medium text (e.g. headers)
    JSON styleTextMedium     = JSON("name", "Helvetica","fill", "none", "alpha", 0.0, "size", 28);

    // Big text (city, zip)
    JSON styleTextBig        = JSON("fill", "none", "alpha", 0.0, "size", 36);

    // Huge right-aligned number
    JSON styleTextHugeRight  = JSON("align", "right", "fill", "none", "alpha", 0.0, "size", 96);

    // Left aligned (default) – used for many small blocks
    JSON styleTextLeft       = styleTextSmall;

    // Box border style used in main address block
    JSON styleAddressBox     = JSON(
        "fill", json("color", "red", "alpha", 0.0),
        "line", json("color", "black")
    );

    // ----------------------------------------------------------------
    // FROM block
    // ----------------------------------------------------------------
    ImageSetFont(img, json("name", "Helvetica", "color", "black", "size", 16, "style", "normal")); 

    ImageDrawTextBox(
        img,
        lm, u_(5),
        w - lm*2, u_(15.5),
        from,
        JSON("align", "left", "size", 20, "alpha", 0.0)
    );

    // ----------------------------------------------------------------
    // Big address box and separator lines
    // ----------------------------------------------------------------
    ImageSetLineStyle(img, JSON("color", "black", "width", 4.0)); 

    float boxtop   = u_(15.5);
    float boxwidth = u_(75); 
    float rm       = boxwidth + lm; 

    ImageRect(img, lm, boxtop, boxwidth, u_(37.5), styleAddressBox);

    float line1 = boxtop + u_(24.5);
    float line2 = boxtop + u_(33.5);
    float line3 = boxtop + u_(52.1); 
    float line4 = boxtop + u_(80.0); 
    float line5 = boxtop + u_(86.0); 
    float line6 = boxtop + u_(99.0); 
    float line7 = boxtop + u_(110.0); 

    ImageLine(img, lm, line1, rm, line1);
    ImageLine(img, lm, line2, rm, line2); 
    ImageLine(img, lm, line3, rm, line3); 
    ImageLine(img, lm, line4, rm, line4); 
    ImageLine(img, lm, line5, rm, line5); 
    ImageLine(img, lm, line6, rm, line6); 
    ImageLine(img, lm, line7, rm, line7, JSON("width", 8)); 

    // ----------------------------------------------------------------
    // TO block
    // ----------------------------------------------------------------
    ImageSetFont(img, json("size", 28, "style", "normal")); 
    string to1 = format("**To:**\n%s", ToName); 

    ImageDrawTextBox(
        img,
        lm + 10, boxtop + 5,
        w - lm*2, u_(37.5),
        to1,
        styleTextBase
    ); 

    ImageSetFont(img, json("size", 36, "style", "normal")); 
    ImageAddText(img, format("**%s**", ToAddr)); 

    // Country row
    ImageDrawTextBox(
        img,
        lm + 10, line2 + 5,
        w - lm*2, u_(10),
        "**" + ToCountry + "**",
        styleTextBase
    );

    // Zip
    ImageSetFont(img, json("name", "Helvetica", "size", 96, "style", "bold")); 
    ImageDrawTextBox(
        img,
        lm + 10, boxtop + u_(17),
        w/2, u_(6.5),
        ToZip,
        styleTextBase
    );  

    // City
    ImageSetFont(img, json("size", 70, "style", "bold")); 
    ImageDrawTextBox(
        img,
        lm + boxwidth/2, boxtop + u_(17),
        w/2, u_(6.5),
        ToCity,
        styleTextBase
    );  

 
    // Phone
    ImageSetFont(img, styleTextMedium); 
    ImageDrawTextBox(
        img,
        lm + u_(55.0), line1 + 5,
        w/4, line2 - line1,
        format("**Phone:**\n%s", ToPhone),
        styleTextMedium
    );  

    // Date
    ImageDrawTextBox(
        img,
        lm + u_(55.0), boxtop + 5,
        w/4, u_(10),
        string(now(), "%d.%m.%Y"),
        styleTextBase
    );  

    // ----------------------------------------------------------------
    // Info table
    // ----------------------------------------------------------------
    float row1 = line3 - u_(12);
    float row2 = line3 - u_(6); 
    float col1 = lm + 5;
    float col2 = lm + u_(35);
    float col3 = lm + u_(48);
    float col4 = lm + u_(60); 

    ImageSetFont(img, json("size", 24, "style", "normal")); 

    ImageDrawTextBox(
        img, col1, row1, w/4, u_(6),
        format("**License Plate No:**\n%s", LicensePlate),
        styleTextBase
    );  

    ImageDrawTextBox(
        img, col1, row2, w/4, u_(6),
        format("**Consignment ID:**\n%s", Consignment),
        styleTextBase
    );  

    ImageDrawTextBox(
        img, col2, row1, w/4, u_(6),
        format("**Packages:**\n**%d/%d**", packages, PackageCount),
        styleTextBase
    );  

    ImageDrawTextBox(
        img, col2, row2, w/4, u_(6),
        format("**Customer No:**\n%s", PostalCustomerNo),
        styleTextBase
    );  

    ImageDrawTextBox(
        img, col3, row1, w/4, u_(6),
        format("**Weight (kg):**\n**%.1f**", weightKg),
        styleTextBase
    );  

    ImageDrawTextBox(
        img, col4, row1, w/4, u_(6),
        format("**Volume (dm%s):**\n**%.1f**", char(179), Volume),
        styleTextBase
    );  

    // ----------------------------------------------------------------
    // Icons & product info
    // ----------------------------------------------------------------
    string delivpers = desktop_directory() + "/deliveryperson.png"; // 185x132
    float imw1 = u_(18.5) * 0.7;
    float imh1 = u_(13.2) * 0.7;

    ImageDrawTextBox(
        img,
        lm + 5, line3 + 5,
        rm - lm - imw1, u_(20),
        format("**Transport Instructions:**\n%s", TransportInstr),
        styleTextBase
    ); 

    ImageAddImage(img, rm - imw1, line3 + 5, imw1, imh1, delivpers);

    string postenlogo = desktop_directory() + "/posten-logo.png"; // 314x413
    float imw2 = u_(31.4) * 0.3;
    float imh2 = u_(41.3) * 0.3;

    ImageAddImage(img, lm + 5, line5 + 5, imw2, imh2, postenlogo);

    // Product info
    ImageSetFont(img, json("size", 24, "style", "normal"));

    ImageDrawTextBox(
        img,
        lm + imw2 + u_(5), line5 + 5,
        rm - lm - imw2, line6 - line5,
        "**Product:**\nNorgespakke\n**product ID:**",
        styleTextBase
    ); 

    ImageDrawTextBox(
        img,
        lm + u_(24), line5 + u_(7),
        rm/4, (line6 - line5)/2,
        "**3067**",
        JSON("fill", "none", "alpha", 0.0, "size", 70)
    ); 

    ImageDrawTextBox(
        img,
        lm, line5 + 7,
        rm - lm, (line6 - line5),
        "**3**",
        styleTextHugeRight
    ); 

    // References
    ImageDrawTextBox(
        img,
        lm + 5, line6 + 10,
        rm - lm, (line6 - line5),
        "Senders reference:\n   293823\n**Recipients reference:**\n   ABC-123",
        JSON("align", "left", "fill", "none", "alpha", 0.0, "size", 24)
    ); 

    // License Plate label
    ImageSetFont(img, json("size", 24, "style", "bold")); 
    ImageDrawTextBox(
        img,
        lm, line7 + 5,
        w - lm*2, u_(15.0),
        "**License plate no:**",
        styleTextBase
    ); 

    // ----------------------------------------------------------------
    // GS1-128 barcode
    // ----------------------------------------------------------------
    JSON styleBar = JSON(
        "type", "gs1-128",
        "fgColor", "black",
        "bgColor", "white",
        "ecLevel", "M",
        "drawtext", true,
        "border", 4,
        "rotate", 0
    );

    ImageAddBarcode(
        img,
        u_(13.0), u_(130.0), u_(55), u_(22),
        "(00)" + LicensePlate,
        styleBar
    );

    string path = desktop_directory() + "/packlabel.png";
    SaveImage(img, path);
    return string(img); 

end