Please bookmark this page to avoid losing your image tool!

Image Workshop Organizer

(Free & Supports Bulk Upload)

Drag & drop your images here or

The result will appear here...
You can edit the below JavaScript code to customize the image tool.
async function processImage(originalImg, title = 'В МАСТЕРСКУЮ!', backgroundColor = '#002244', lineColor = '#FFFFFF', threshold = 50, addGrid = 'true', gridSize = 50) {
    /**
     * Dynamically loads a Google Font if it's not already available.
     * @param {string} fontName The name of the font to load.
     */
    const loadFont = async (fontName) => {
        const fontUrl = `https://fonts.googleapis.com/css2?family=${fontName.replace(/ /g, '+')}&display=swap`;
        if (!document.querySelector(`link[href="${fontUrl}"]`)) {
            const link = document.createElement('link');
            link.rel = 'stylesheet';
            link.href = fontUrl;
            document.head.appendChild(link);
            try {
                await document.fonts.load(`1em "${fontName}"`);
            } catch (err) {
                console.error(`Font ${fontName} could not be loaded:`, err);
            }
        }
    };

    /**
     * Converts a HEX color string to an RGB object.
     * @param {string} hex The hex color string (e.g., '#FF5733').
     * @returns {{r: number, g: number, b: number}|null}
     */
    const hexToRgb = (hex) => {
        const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
        return result ? {
            r: parseInt(result[1], 16),
            g: parseInt(result[2], 16),
            b: parseInt(result[3], 16)
        } : null;
    };

    await loadFont('Share Tech Mono');

    const canvas = document.createElement('canvas');
    const width = originalImg.naturalWidth;
    const height = originalImg.naturalHeight;
    canvas.width = width;
    canvas.height = height;
    // The 'willReadFrequently' hint can optimize repeated getImageData/putImageData calls.
    const ctx = canvas.getContext('2d', { willReadFrequently: true });

    // Draw the original image to a temporary canvas to get its pixel data.
    ctx.drawImage(originalImg, 0, 0);
    const imageData = ctx.getImageData(0, 0, width, height);
    const data = imageData.data;

    const bgRgb = hexToRgb(backgroundColor);
    const lineRgb = hexToRgb(lineColor);
    if (!bgRgb || !lineRgb) {
        console.error("Invalid background or line color provided.");
        return canvas; // Return empty canvas on error
    }

    // Convert the image to grayscale for edge detection.
    const grayscaleData = new Uint8ClampedArray(width * height);
    for (let i = 0; i < data.length; i += 4) {
        const r = data[i];
        const g = data[i + 1];
        const b = data[i + 2];
        const gray = 0.299 * r + 0.587 * g + 0.114 * b;
        grayscaleData[i / 4] = gray;
    }

    // Apply the Sobel operator to detect edges.
    const sobelData = new Float32Array(width * height);
    const Gx = [
        [-1, 0, 1],
        [-2, 0, 2],
        [-1, 0, 1]
    ];
    const Gy = [
        [-1, -2, -1],
        [0, 0, 0],
        [1, 2, 1]
    ];

    for (let y = 1; y < height - 1; y++) {
        for (let x = 1; x < width - 1; x++) {
            let sumX = 0;
            let sumY = 0;
            for (let i = -1; i <= 1; i++) {
                for (let j = -1; j <= 1; j++) {
                    const gray = grayscaleData[(y + i) * width + (x + j)];
                    sumX += gray * Gx[i + 1][j + 1];
                    sumY += gray * Gy[i + 1][j + 1];
                }
            }
            const magnitude = Math.sqrt(sumX * sumX + sumY * sumY);
            sobelData[y * width + x] = magnitude;
        }
    }

    // Create the final blueprint image data.
    const outputImageData = ctx.createImageData(width, height);
    const outputData = outputImageData.data;
    for (let i = 0; i < sobelData.length; i++) {
        const magnitude = sobelData[i];
        const pixelIndex = i * 4;
        const color = magnitude > threshold ? lineRgb : bgRgb;
        outputData[pixelIndex] = color.r;
        outputData[pixelIndex + 1] = color.g;
        outputData[pixelIndex + 2] = color.b;
        outputData[pixelIndex + 3] = 255;
    }

    ctx.putImageData(outputImageData, 0, 0);

    // Add optional grid lines for a more technical look.
    if (addGrid === 'true' && gridSize > 0) {
        ctx.strokeStyle = lineColor;
        ctx.globalAlpha = 0.2;
        ctx.lineWidth = 1;
        for (let x = Number(gridSize); x < width; x += Number(gridSize)) {
            ctx.beginPath();
            ctx.moveTo(x, 0);
            ctx.lineTo(x, height);
            ctx.stroke();
        }
        for (let y = Number(gridSize); y < height; y += Number(gridSize)) {
            ctx.beginPath();
            ctx.moveTo(0, y);
            ctx.lineTo(width, y);
            ctx.stroke();
        }
        ctx.globalAlpha = 1.0;
    }

    // Add an optional title block in the corner.
    if (title) {
        const fontSize = Math.max(16, Math.min(width / 25, height / 25));
        const padding = fontSize * 0.5;
        
        ctx.font = `${fontSize}px "Share Tech Mono", monospace`;
        ctx.textAlign = 'right';
        ctx.textBaseline = 'bottom';
        
        const textMetrics = ctx.measureText(title);
        const boxWidth = textMetrics.width + 2 * padding;
        const boxHeight = fontSize + 2 * padding;
        const boxX = width - boxWidth - padding;
        const boxY = height - boxHeight - padding;

        ctx.strokeStyle = lineColor;
        ctx.fillStyle = backgroundColor;
        ctx.lineWidth = 2;
        ctx.fillRect(boxX, boxY, boxWidth, boxHeight);
        ctx.strokeRect(boxX, boxY, boxWidth, boxHeight);
        
        ctx.fillStyle = lineColor;
        ctx.fillText(title, width - 2 * padding, height - 2 * padding);
    }

    return canvas;
}

Free Image Tool Creator

Can't find the image tool you're looking for?
Create one based on your own needs now!

Description

The Image Workshop Organizer is a versatile online tool that allows users to enhance and process images with a variety of features. It can convert images into a high-contrast blueprint style, applying edge detection to highlight important details. Users can customize the output with options for background and line colors, add grid lines for precision, and include text titles for better presentation. This tool is ideal for artists, architects, and designers looking to create detailed presentations or prototypes, as well as for educators and students needing to visualize concepts through clear, structured images.

Leave a Reply

Your email address will not be published. Required fields are marked *