You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(
originalImg,
dlNumber = "12345678",
dob = "01/01/1990",
exp = "01/01/2030",
lastName = "DOE",
givenName = "JOHN",
address1 = "123 TEXAS AVE",
address2 = "AUSTIN, TX 78701",
sex = "M",
height = "5-10",
eyes = "BRO",
hair = "BLK",
classType = "C"
) {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
// Standard ID aspect ratio
canvas.width = 800;
canvas.height = 504;
// 1. Draw Base Background Gradient (Light Blue to White to Pink)
const bgGradient = ctx.createLinearGradient(0, 0, canvas.width, canvas.height);
bgGradient.addColorStop(0, '#e3f2fd');
bgGradient.addColorStop(0.5, '#ffffff');
bgGradient.addColorStop(1, '#ffebee');
ctx.fillStyle = bgGradient;
ctx.fillRect(0, 0, canvas.width, canvas.height);
// 2. Draw Repeating Security Watermark Background
ctx.save();
ctx.font = 'bold 36px Arial';
ctx.fillStyle = 'rgba(0, 0, 0, 0.03)';
ctx.rotate(-Math.PI / 6);
for (let i = -15; i < 25; i++) {
for (let j = -10; j < 25; j++) {
ctx.fillText('TEXAS', i * 160, j * 90);
}
}
ctx.restore();
// Helper: Draw Star Function
const drawStar = (x, y, spikes, outerRadius, innerRadius) => {
let rot = Math.PI / 2 * 3;
let step = Math.PI / spikes;
ctx.beginPath();
ctx.moveTo(x, y - outerRadius);
for (let i = 0; i < spikes; i++) {
ctx.lineTo(x + Math.cos(rot) * outerRadius, y + Math.sin(rot) * outerRadius);
rot += step;
ctx.lineTo(x + Math.cos(rot) * innerRadius, y + Math.sin(rot) * innerRadius);
rot += step;
}
ctx.lineTo(x, y - outerRadius);
ctx.closePath();
ctx.fill();
};
// 3. Draw Faint Large Center Star (Gold/Yellow)
ctx.fillStyle = 'rgba(255, 215, 0, 0.15)';
drawStar(canvas.width / 2, canvas.height / 2, 5, 180, 68);
// 4. Header: Texas Flag (Top Left)
ctx.fillStyle = '#002868'; // Blue
ctx.fillRect(40, 20, 60, 80);
ctx.fillStyle = '#ffffff'; // White
ctx.fillRect(100, 20, 90, 40);
ctx.fillStyle = '#bf0a30'; // Red
ctx.fillRect(100, 60, 90, 40);
// Flag Star
ctx.fillStyle = '#ffffff';
drawStar(70, 60, 5, 16, 6);
// 5. Header: Titles
ctx.font = 'bold 55px Arial';
ctx.fillStyle = '#111111';
ctx.fillText('TEXAS', 220, 65);
ctx.font = 'bold 22px Arial';
ctx.fillStyle = '#005b96';
ctx.fillText('DRIVER LICENSE', 222, 95);
ctx.font = 'bold italic 28px "Times New Roman", Times, serif';
ctx.fillStyle = '#002868';
ctx.fillText('USA', 700, 50);
// Decorative Line under header
ctx.strokeStyle = '#005b96';
ctx.lineWidth = 3;
ctx.beginPath();
ctx.moveTo(35, 112);
ctx.lineTo(765, 112);
ctx.stroke();
// 6. Handle Main Portrait and Ghost Photo Crop
const dw = 200;
const dh = 260;
const imgRatio = originalImg.width / originalImg.height;
const targetRatio = dw / dh;
let sx, sy, sw, sh;
if (imgRatio > targetRatio) {
sh = originalImg.height;
sw = sh * targetRatio;
sx = (originalImg.width - sw) / 2;
sy = 0;
} else {
sw = originalImg.width;
sh = sw / targetRatio;
sx = 0;
sy = (originalImg.height - sh) / 2;
}
// Main Photo
ctx.drawImage(originalImg, sx, sy, sw, sh, 40, 125, dw, dh);
ctx.strokeStyle = '#222';
ctx.lineWidth = 2;
ctx.strokeRect(40, 125, dw, dh);
// Ghost Photo
ctx.globalAlpha = 0.35;
ctx.drawImage(originalImg, sx, sy, sw, sh, 620, 270, 120, 156);
ctx.globalAlpha = 1.0;
// 7. Render Data Fields
const drawField = (label, value, x, y, scale = 1) => {
ctx.font = 'bold 11px Arial';
ctx.fillStyle = '#b71c1c'; // Deep Red Label
ctx.fillText(label, x, y);
if (value) {
ctx.font = `bold ${Math.round(16 * scale)}px Arial`;
ctx.fillStyle = '#000000'; // Black Value
ctx.fillText(String(value).toUpperCase(), x, y + Math.round(16 * scale) + 4);
}
};
// Row 1
drawField('4d DL No.', dlNumber, 260, 135, 1.25);
drawField('3 DOB', dob, 460, 135, 1.25);
drawField('9 CLASS', classType, 660, 135, 1.25);
// Row 2
drawField('4b EXP', exp, 260, 195, 1.1);
// Row 3
drawField('1 LAST NAME', lastName, 260, 250, 1.4);
// Row 4
drawField('2 FIRST NAME', givenName, 260, 310, 1.3);
// Row 5 (Address)
ctx.font = 'bold 11px Arial';
ctx.fillStyle = '#b71c1c';
ctx.fillText('8 ADDRESS', 260, 370);
ctx.font = 'bold 18px Arial';
ctx.fillStyle = '#000';
if (address1) ctx.fillText(address1.toUpperCase(), 260, 390);
if (address2) ctx.fillText(address2.toUpperCase(), 260, 412);
// Row 6 (Physical Specs)
drawField('15 SEX', sex, 260, 445);
drawField('16 HGT', height, 330, 445);
drawField('18 EYES', eyes, 400, 445);
drawField('19 HAIR', hair, 470, 445);
// 8. Add Signature
if (givenName || lastName) {
ctx.font = 'italic 28px cursive';
ctx.fillStyle = '#111';
ctx.textAlign = 'center';
// Assemble proper name even if one piece is missing
let fullName = [];
if (givenName) fullName.push(givenName);
if (lastName) fullName.push(lastName);
ctx.fillText(fullName.join(' '), 40 + dw / 2, 430);
ctx.textAlign = 'left'; // reset
}
return canvas;
}
Apply Changes