Please bookmark this page to avoid losing your image tool!

Image Retro Futuristic Patent Drawing Creator

(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.
function processImage(originalImg, gridColor = 'rgba(70, 170, 220, 0.6)', backgroundColor = '#0A101A', gridSpacing = 25, gridLineWidth = 0.5, sketchLineColorStr = 'rgba(220, 240, 255, 0.9)', blurRadius = 2, sketchThreshold = 100) {

    // Helper function to parse color string to an RGBA object
    function parseColorToRGBA(colorStr) {
        const canvas = document.createElement('canvas');
        canvas.width = 1;
        canvas.height = 1;
        const ctx = canvas.getContext('2d');
        if (!ctx) { // Fallback if context creation fails
            // Try to guess some common colors if canvas fails, though unlikely
            if (colorStr === 'transparent') return { r:0, g:0, b:0, a:0 };
            return { r: 0, g: 0, b: 0, a: 1 }; // Default to black
        }

        ctx.fillStyle = colorStr;
        ctx.fillRect(0, 0, 1, 1);
        const data = ctx.getImageData(0, 0, 1, 1).data;
        return { r: data[0], g: data[1], b: data[2], a: data[3] / 255.0 };
    }

    const w = originalImg.naturalWidth || originalImg.width;
    const h = originalImg.naturalHeight || originalImg.height;

    if (w === 0 || h === 0) {
        // Handle cases where the image has no dimensions (e.g., not loaded yet)
        const emptyCanvas = document.createElement('canvas');
        emptyCanvas.width = 1; // Return a minimal canvas
        emptyCanvas.height = 1;
        return emptyCanvas;
    }

    const parsedSketchLineColor = parseColorToRGBA(sketchLineColorStr);

    // Create temporary canvases
    // Use { willReadFrequently: true } for potential performance hint if supported
    const canvas1 = document.createElement('canvas');
    canvas1.width = w;
    canvas1.height = h;
    const ctx1 = canvas1.getContext('2d', { willReadFrequently: true });

    const canvas2 = document.createElement('canvas');
    canvas2.width = w;
    canvas2.height = h;
    const ctx2 = canvas2.getContext('2d', { willReadFrequently: true });

    // 1. Draw original image and convert to grayscale on canvas1
    ctx1.drawImage(originalImg, 0, 0, w, h);
    const imgData = ctx1.getImageData(0, 0, w, h);
    const data = imgData.data;
    for (let i = 0; i < data.length; i += 4) {
        const r = data[i];
        const g = data[i + 1];
        const b = data[i + 2];
        // Standard luminance calculation
        const gray = 0.299 * r + 0.587 * g + 0.114 * b;
        data[i] = data[i + 1] = data[i + 2] = gray;
        // Alpha (data[i+3]) is preserved
    }
    ctx1.putImageData(imgData, 0, 0); // canvas1 now has grayscale image

    // 2. Create blurred-inverted-grayscale version on canvas2
    //    canvas1 (grayscale) is drawn to canvas2, applying filter in the process.
    ctx2.filter = `invert(100%) blur(${blurRadius}px)`;
    ctx2.drawImage(canvas1, 0, 0, w, h); // canvas2 now has blurred-inverted-grayscale image

    // 3. Color Dodge blend
    //    Get data from grayscale (canvas1) and blurred-inverted (canvas2)
    const grayscalePixelData = ctx1.getImageData(0, 0, w, h).data;
    const blurredInvertedPixelData = ctx2.getImageData(0, 0, w, h).data;
    
    const sketchImageData = ctx1.createImageData(w, h);
    const sketchData = sketchImageData.data;

    for (let i = 0; i < sketchData.length; i += 4) {
        const grayVal = grayscalePixelData[i]; // R channel is fine, it's grayscale
        const blurInvVal = blurredInvertedPixelData[i]; // R channel
        const originalAlpha = grayscalePixelData[i+3]; // Alpha from original grayscale image

        let dodgeVal;
        if (blurInvVal === 255) { // If the "blend" (blurred-inverted) is white
            dodgeVal = blurInvVal; // Result is white
        } else if (grayVal === 0) { // if the "base" (grayscale) is black
             dodgeVal = 0; // Result is black
        }
        else {
            // Color Dodge formula: Result = BaseColor / (1 - BlendColor/255)
            // Which is equivalent to: (BaseColor * 255) / (255 - BlendColor)
            dodgeVal = (grayVal * 255.0) / (255.0 - blurInvVal);
            dodgeVal = Math.min(255, dodgeVal); // Clamp to 255
        }
        
        sketchData[i] = sketchData[i+1] = sketchData[i+2] = dodgeVal;
        sketchData[i+3] = originalAlpha; // Preserve alpha from the grayscale image
    }
    ctx1.putImageData(sketchImageData, 0, 0); // canvas1 now has "sketch" (dark lines, light bg)

    // 4. Process sketch: make lines colored according to sketchLineColor, rest transparent
    const finalLinesImageData = ctx1.getImageData(0, 0, w, h);
    const flData = finalLinesImageData.data;

    for (let i = 0; i < flData.length; i += 4) {
        const intensity = flData[i]; // R channel of sketch (it's grayscale)
        const alpha = flData[i+3]; // Current alpha of sketch pixel

        if (alpha === 0) continue; // Skip if already fully transparent

        // If pixel intensity is below threshold, it's a line
        if (intensity < sketchThreshold) { 
            flData[i]   = parsedSketchLineColor.r;
            flData[i+1] = parsedSketchLineColor.g;
            flData[i+2] = parsedSketchLineColor.b;
            flData[i+3] = parsedSketchLineColor.a * 255; // Apply sketchLineColor alpha
        } else { // Lighter background parts become transparent
            flData[i+3] = 0;
        }
    }
    ctx1.putImageData(finalLinesImageData, 0, 0); // canvas1 now has colored lines on transparent bg

    // 5. Final Composition
    const finalCanvas = document.createElement('canvas');
    finalCanvas.width = w;
    finalCanvas.height = h;
    const finalCtx = finalCanvas.getContext('2d');

    // Draw background color
    finalCtx.fillStyle = backgroundColor;
    finalCtx.fillRect(0, 0, w, h);

    // Draw grid
    if (gridSpacing > 0 && gridLineWidth > 0) {
        finalCtx.strokeStyle = gridColor;
        finalCtx.lineWidth = gridLineWidth;
        finalCtx.beginPath();
        for (let x = gridSpacing; x < w; x += gridSpacing) {
            finalCtx.moveTo(x + gridLineWidth / 2, 0); // Offset by half line width for sharper lines
            finalCtx.lineTo(x + gridLineWidth / 2, h);
        }
        for (let y = gridSpacing; y < h; y += gridSpacing) {
            finalCtx.moveTo(0, y + gridLineWidth / 2);
            finalCtx.lineTo(w, y + gridLineWidth / 2);
        }
        finalCtx.stroke();
    }

    // Draw the processed lines (from canvas1) onto the final canvas
    finalCtx.drawImage(canvas1, 0, 0, w, h);

    return finalCanvas;
}

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 Retro Futuristic Patent Drawing Creator is a tool designed to transform images into a retro-style patent drawing aesthetic. It accomplishes this by converting the input image to grayscale, applying a sketch effect with colored lines, and allowing for customization of background and grid elements. This tool can be particularly useful for artists, designers, or anyone looking to create unique visuals for presentations, marketing materials, or personal projects that require an artistic twist reminiscent of vintage patent illustrations.

Leave a Reply

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