âœï¸ 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,...
How It Works
- Build a Joget form hash variable from the incoming
table,field, andidvalues. - Use
AppUtil.processHashVariableto read the signature JSON. - URL-decode the returned signature payload.
- Parse the payload as a JSON array of stroke coordinates.
- Draw each stroke onto a
BufferedImage. - Encode the generated PNG as Base64.
- 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
]#
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">
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 "";
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
widthandheightto match your report or PDF layout. - Increase the
BasicStrokevalue if the signature appears too thin. - Use a transparent image type if your output needs a non-white background.
- Keep
table,field, andiddynamic 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)