DEV Community

Explorer
Explorer

Posted on • Edited on

✍️ Convert Joget Signature Field JSON to a Base64 PNG Image

✍️ Convert Joget Signature Field JSON to a Base64 PNG Image

Published URL: https://dev.to/exploringmylifeworks/convert-joget-signature-field-to-image-generic-dynamic-table-field-and-id-4bg3

Status: DONE_SOURCE_CODE_SYNCED
Last synced: 2026-05-29T15:05:00Z


Overview

Joget signature fields store the signature as stroke JSON. That is useful for capturing the drawing, but reports, PDF templates, emails, and previews often need a normal image.

This BeanShell script reads a signature field dynamically using table, field, and id parameters, converts the stroke JSON into a PNG, and returns a Base64 data URL like:

data:image/png;base64,...
Enter fullscreen mode Exit fullscreen mode

How It Works

  1. Build a Joget form hash variable from the incoming table, field, and id values.
  2. Use AppUtil.processHashVariable to read the signature JSON.
  3. URL-decode the returned signature payload.
  4. Parse the payload as a JSON array of stroke coordinates.
  5. Draw each stroke onto a BufferedImage.
  6. Encode the generated PNG as Base64.
  7. Return the image as a browser-ready data URL.

Where to Use in Joget

Use this in Form Builder, Userview, reports, or any place where a BeanShell hash variable output can be rendered as an image source.

Example usage:

#beanshell.generateSignature[
  table=app_fd_your_form&
  field=c_signature&
  id=your_record_id
]#
Enter fullscreen mode Exit fullscreen mode

In HTML output, you can render the result like this:

<img src="#beanshell.generateSignature[table=app_fd_your_form&field=c_signature&id=your_record_id]#" alt="Signature">
Enter fullscreen mode Exit fullscreen mode

Full Code

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.net.URLDecoder;
import java.util.Base64;
import javax.imageio.ImageIO;
import org.joget.apps.app.service.AppUtil;
import org.joget.commons.util.LogUtil;
import org.json.JSONArray;
import org.json.JSONObject;

public String generateJSON(String table, String fieldName, String recordId) {
    String signatureHash =
        "#form." + table + "." + fieldName + "[" + recordId + "]?url#";

    return AppUtil.processHashVariable(signatureHash, null, null, null);
}

String tableName = table[0];
String fieldName = field[0];
String recordId = id[0];

LogUtil.info(
    "generateSignature",
    "Params -> table=" + tableName + ", field=" + fieldName + ", id=" + recordId
);

int width = 200;
int height = 80;

try {
    String jsonString = URLDecoder.decode(
        generateJSON(tableName, fieldName, recordId),
        "UTF-8"
    );

    JSONArray strokes = new JSONArray(jsonString);
    BufferedImage signatureImage = new BufferedImage(
        width,
        height,
        BufferedImage.TYPE_INT_RGB
    );

    Graphics2D g2 = signatureImage.createGraphics();
    g2.setColor(Color.WHITE);
    g2.fillRect(0, 0, width, height);
    g2.setPaint(Color.BLACK);
    g2.setStroke(new BasicStroke(2));
    g2.setRenderingHint(
        RenderingHints.KEY_ANTIALIASING,
        RenderingHints.VALUE_ANTIALIAS_ON
    );

    for (int i = 0; i < strokes.length(); i++) {
        JSONObject point = strokes.getJSONObject(i);
        g2.drawLine(
            point.getInt("lx"),
            point.getInt("ly"),
            point.getInt("mx"),
            point.getInt("my")
        );
    }

    g2.dispose();

    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ImageIO.setUseCache(false);
    ImageIO.write(signatureImage, "png", baos);
    baos.flush();

    String base64Image = Base64.getEncoder().encodeToString(baos.toByteArray());
    baos.close();

    return "data:image/png;base64," + base64Image;
} catch (Exception e) {
    LogUtil.error("generateSignature", e, "Unable to convert signature JSON to image.");
}

return "";
Enter fullscreen mode Exit fullscreen mode

Example Use Cases

  • Show a captured signature inside a Userview page.
  • Embed a signature into a generated PDF.
  • Add a signature image to an email template.
  • Render signature previews in custom reports.

Customization Tips

  • Adjust width and height to match your report or PDF layout.
  • Increase the BasicStroke value if the signature appears too thin.
  • Use a transparent image type if your output needs a non-white background.
  • Keep table, field, and id dynamic so the same script can be reused across forms.

Security Note

Do not publish real table names, field IDs, record IDs, or business-specific schema names. Use placeholders in public examples and map them to your actual Joget form table only inside your private environment.

Final Thoughts

This is a practical pattern when Joget stores signature data as JSON but your workflow needs an actual image. The important part is that the conversion stays reusable: pass the table, signature field, and record ID dynamically, then return a Base64 PNG that can be rendered anywhere HTML accepts an image source.

Top comments (0)