You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(
originalImg,
studioName = "МЕЖДУНАРОДНАЯ КИНОСТУДИЯ",
dbTitle = "БАЗА ДАННЫХ АКТЕРОВ // RECORD",
recordId = "ID-774-X9",
subjectName = "Неизвестный Объект",
roleAssign = "Главная Роль / Main Cast",
statusText = "УТВЕРЖДЕН К СЪЕМКЕ",
themeColor = "#121212",
accentColor = "#ffb700"
) {
// Create canvas
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
// Set dimensions
const width = 850;
const height = 500;
canvas.width = width;
canvas.height = height;
// 1. Draw Background
ctx.fillStyle = themeColor;
ctx.fillRect(0, 0, width, height);
// 2. Draw Film Strip Perforations (Top and Bottom)
ctx.fillStyle = "#000000";
ctx.fillRect(0, 0, width, 40);
ctx.fillRect(0, height - 40, width, 40);
ctx.fillStyle = "#ffffff";
for (let i = 15; i < width; i += 40) {
// Top perforations
drawRoundRect(ctx, i, 10, 20, 20, 4);
ctx.fill();
// Bottom perforations
drawRoundRect(ctx, i, height - 30, 20, 20, 4);
ctx.fill();
}
// 3. Draw Main Database Interface Box
const uiX = 50;
const uiY = 60;
const uiW = width - 100;
const uiH = height - 120;
ctx.strokeStyle = "#444444";
ctx.lineWidth = 2;
ctx.strokeRect(uiX, uiY, uiW, uiH);
ctx.fillStyle = "#1e1e1e";
ctx.fillRect(uiX, uiY, uiW, uiH);
// 4. Draw Header
ctx.fillStyle = accentColor;
ctx.fillRect(uiX, uiY, uiW, 40);
ctx.fillStyle = "#000000";
ctx.font = "bold 20px 'Courier New', Courier, monospace";
ctx.textAlign = "left";
ctx.textBaseline = "middle";
ctx.fillText(`${studioName} | ${dbTitle}`, uiX + 15, uiY + 20);
// 5. Image Area (Left)
const imgSize = 260;
const imgX = uiX + 20;
const imgY = uiY + 60;
// Provide a border for the image
ctx.strokeStyle = accentColor;
ctx.lineWidth = 3;
ctx.strokeRect(imgX - 2, imgY - 2, imgSize + 4, imgSize + 4);
// Crop and draw the image to fit the square
const scale = Math.max(imgSize / originalImg.width, imgSize / originalImg.height);
const w = originalImg.width * scale;
const h = originalImg.height * scale;
const ix = imgX + (imgSize - w) / 2;
const iy = imgY + (imgSize - h) / 2;
ctx.save();
ctx.beginPath();
ctx.rect(imgX, imgY, imgSize, imgSize);
ctx.clip();
// Draw actual image
ctx.drawImage(originalImg, ix, iy, w, h);
// Add subtle scanlines over the image for database/system feel
ctx.fillStyle = "rgba(0, 0, 0, 0.2)";
for (let sy = imgY; sy < imgY + imgSize; sy += 4) {
ctx.fillRect(imgX, sy, imgSize, 1);
}
// Add a slight color tint
ctx.fillStyle = `${accentColor}11`; // Hex with low opacity
ctx.fillRect(imgX, imgY, imgSize, imgSize);
ctx.restore();
// 6. Draw Database Text Fields (Right Side)
const textX = imgX + imgSize + 40;
let textY = imgY + 20;
const printField = (label, value, yOffset, isHighlighted = false) => {
ctx.fillStyle = "#888888";
ctx.font = "14px 'Courier New', Courier, monospace";
ctx.fillText(label, textX, yOffset);
ctx.fillStyle = isHighlighted ? accentColor : "#ffffff";
ctx.font = "bold 22px 'Courier New', Courier, monospace";
ctx.fillText(value, textX, yOffset + 22);
};
printField("СИСТЕМНЫЙ НОМЕР (RECORD ID):", recordId, textY);
textY += 65;
printField("ИМЯ / СУБЪЕКТ (SUBJECT):", subjectName, textY);
textY += 65;
printField("НАЗНАЧЕНИЕ (ROLE):", roleAssign, textY);
textY += 65;
printField("СТАТУС (STATUS):", statusText, textY, true);
// 7. Draw Decorative "Database" Barcode
const bcX = textX;
const bcY = imgY + imgSize - 40;
const bcW = uiX + uiW - textX - 20;
const bcH = 40;
ctx.fillStyle = "#ffffff";
ctx.fillRect(bcX, bcY, bcW, bcH);
ctx.fillStyle = "#000000";
let currentX = bcX + 10;
const seedText = recordId + subjectName + roleAssign;
// Generate pseudo-random barcode based on the input text
for (let i = 0; i < seedText.length * 5 && currentX < bcX + bcW - 10; i++) {
let barW = (seedText.charCodeAt(i % seedText.length) % 5) + 1;
let spaceW = (seedText.charCodeAt((i + 1) % seedText.length) % 3) + 1;
if (currentX + barW > bcX + bcW - 10) barW = (bcX + bcW - 10) - currentX;
ctx.fillRect(currentX, bcY + 5, barW, bcH - 10);
currentX += barW + spaceW;
}
// 8. Add Corner Brackets (for techy/camera viewfinder look)
ctx.strokeStyle = accentColor;
ctx.lineWidth = 2;
const bLen = 15;
// Top-Left
ctx.beginPath();
ctx.moveTo(imgX, imgY + bLen); ctx.lineTo(imgX, imgY); ctx.lineTo(imgX + bLen, imgY);
ctx.stroke();
// Top-Right
ctx.beginPath();
ctx.moveTo(imgX + imgSize - bLen, imgY); ctx.lineTo(imgX + imgSize, imgY); ctx.lineTo(imgX + imgSize, imgY + bLen);
ctx.stroke();
// Bottom-Left
ctx.beginPath();
ctx.moveTo(imgX, imgY + imgSize - bLen); ctx.lineTo(imgX, imgY + imgSize); ctx.lineTo(imgX + bLen, imgY + imgSize);
ctx.stroke();
// Bottom-Right
ctx.beginPath();
ctx.moveTo(imgX + imgSize - bLen, imgY + imgSize); ctx.lineTo(imgX + imgSize, imgY + imgSize); ctx.lineTo(imgX + imgSize, imgY + imgSize - bLen);
ctx.stroke();
return canvas;
// Helper function to draw rounded rectangles
function drawRoundRect(context, x, y, w, h, radius) {
context.beginPath();
context.moveTo(x + radius, y);
context.lineTo(x + w - radius, y);
context.quadraticCurveTo(x + w, y, x + w, y + radius);
context.lineTo(x + w, y + h - radius);
context.quadraticCurveTo(x + w, y + h, x + w - radius, y + h);
context.lineTo(x + radius, y + h);
context.quadraticCurveTo(x, y + h, x, y + h - radius);
context.lineTo(x, y + radius);
context.quadraticCurveTo(x, y, x + radius, y);
context.closePath();
}
}
Apply Changes