Please bookmark this page to avoid losing your image tool!

Photo Of Abandoned Sci-Fi Universe Captured From Doorbell Camera

(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.
/**
 * Creates a "weirdcore" image of a sci-fi universe as if captured from an old,
 * distorted doorbell camera. This function applies a fisheye (barrel distortion)
 * effect, desaturates the image, adds grain, a color tint, a vignette, and a
 * circular bezel to simulate the look of a peephole camera.
 *
 * @param {HTMLImageElement} originalImg The original image to process.
 * @param {number} distortion The strength of the fisheye effect (0 for none, 0.5 is a good start). Defaults to 0.5.
 * @param {number} grain The amount of noise/grain to add (0-255). Defaults to 30.
 * @param {number} saturation The color saturation level (0 is grayscale, 1 is original color). Defaults to 0.2.
 * @param {string} tintColor The color of the tint overlay (e.g., '#00ff44'). Defaults to '#00ff44'.
 * @param {number} tintStrength The opacity of the color tint (0 to 1). Defaults to 0.15.
 * @param {number} vignette The darkness of the vignette at the edges (0 to 1). Defaults to 0.6.
 * @returns {HTMLCanvasElement} A canvas element displaying the processed image.
 */
function processImage(originalImg, distortion = 0.5, grain = 30, saturation = 0.2, tintColor = '#00ff44', tintStrength = 0.15, vignette = 0.6) {
    // 1. SETUP
    // Use the smaller dimension to create a square canvas
    const size = Math.min(originalImg.width, originalImg.height);
    const canvas = document.createElement('canvas');
    canvas.width = canvas.height = size;
    const ctx = canvas.getContext('2d');

    if (!ctx) {
        console.error("Canvas context is not available.");
        return document.createElement('div').innerText = "Could not process image.";
    }

    const centerX = size / 2;
    const centerY = size / 2;
    const radius = size / 2;

    // 2. FISHEYE/BARREL DISTORTION PASS
    // This pass remaps pixels from the source image to the destination canvas
    // to create a stretched, rounded effect.

    // Create a temporary canvas to get source image data without affecting the original
    const tempCanvas = document.createElement('canvas');
    tempCanvas.width = originalImg.width;
    tempCanvas.height = originalImg.height;
    const tempCtx = tempCanvas.getContext('2d');
    tempCtx.drawImage(originalImg, 0, 0);
    const srcData = tempCtx.getImageData(0, 0, originalImg.width, originalImg.height);
    const srcPixels = srcData.data;

    const destData = ctx.createImageData(size, size);
    const destPixels = destData.data;

    const srcCenterX = originalImg.width / 2;
    const srcCenterY = originalImg.height / 2;
    const srcRadius = Math.min(srcCenterX, srcCenterY);

    // Distortion strength (k) should be non-negative for barrel distortion
    const k = Math.max(0, distortion);

    for (let y = 0; y < size; y++) {
        for (let x = 0; x < size; x++) {
            const dx = x - centerX;
            const dy = y - centerY;
            const dist = Math.sqrt(dx * dx + dy * dy);

            const destIndex = (y * size + x) * 4;

            if (dist < radius) {
                const angle = Math.atan2(dy, dx);
                // Normalize distance from center [0, 1]
                const normalizedDist = dist / radius;

                // Apply inverse barrel distortion formula to find the source pixel
                const distortedNormDist = Math.pow(normalizedDist, 1.0 / (1.0 + k));
                const srcDist = distortedNormDist * srcRadius;

                // Calculate source coordinates
                let srcX = Math.floor(srcCenterX + srcDist * Math.cos(angle));
                let srcY = Math.floor(srcCenterY + srcDist * Math.sin(angle));

                // Clamp coordinates to be within source bounds
                srcX = Math.max(0, Math.min(originalImg.width - 1, srcX));
                srcY = Math.max(0, Math.min(originalImg.height - 1, srcY));

                const srcIndex = (srcY * originalImg.width + srcX) * 4;

                // Copy RGBA values
                destPixels[destIndex] = srcPixels[srcIndex];
                destPixels[destIndex + 1] = srcPixels[srcIndex + 1];
                destPixels[destIndex + 2] = srcPixels[srcIndex + 2];
                destPixels[destIndex + 3] = 255;
            } else {
                // Pixels outside the circle are transparent
                destPixels[destIndex + 3] = 0;
            }
        }
    }
    ctx.putImageData(destData, 0, 0);

    // 3. COLOR GRADING PASS
    // Use an intermediate canvas to apply CSS-like filters
    const filterCanvas = document.createElement('canvas');
    filterCanvas.width = filterCanvas.height = size;
    const filterCtx = filterCanvas.getContext('2d');

    // Desaturate, increase contrast, and slightly darken the image
    filterCtx.filter = `saturate(${saturation}) contrast(1.2) brightness(0.9)`;
    filterCtx.drawImage(canvas, 0, 0); // Filter is applied on draw
    ctx.clearRect(0, 0, size, size); // Clear main canvas
    ctx.drawImage(filterCanvas, 0, 0); // Draw filtered image back

    // 4. COLOR TINT PASS
    if (tintStrength > 0) {
        ctx.globalCompositeOperation = 'overlay';
        ctx.fillStyle = tintColor;
        ctx.globalAlpha = tintStrength;
        ctx.fillRect(0, 0, size, size);
        ctx.globalAlpha = 1.0;
        ctx.globalCompositeOperation = 'source-over';
    }

    // 5. GRAIN/NOISE PASS
    if (grain > 0) {
        const imageData = ctx.getImageData(0, 0, size, size);
        const pixels = imageData.data;
        for (let i = 0; i < pixels.length; i += 4) {
            // Only apply grain to non-transparent pixels (inside the circle)
            if (pixels[i + 3] > 0) {
                const noise = (Math.random() - 0.5) * grain;
                pixels[i] = Math.max(0, Math.min(255, pixels[i] + noise)); // R
                pixels[i + 1] = Math.max(0, Math.min(255, pixels[i + 1] + noise)); // G
                pixels[i + 2] = Math.max(0, Math.min(255, pixels[i + 2] + noise)); // B
            }
        }
        ctx.putImageData(imageData, 0, 0);
    }

    // 6. VIGNETTE PASS
    if (vignette > 0) {
        const gradient = ctx.createRadialGradient(centerX, centerY, radius * 0.3, centerX, centerY, radius);
        gradient.addColorStop(0, 'rgba(0,0,0,0)');
        gradient.addColorStop(1, `rgba(0,0,0,${vignette})`);
        ctx.fillStyle = gradient;
        ctx.fillRect(0, 0, size, size);
    }

    // 7. DOORBELL BEZEL PASS
    // Draw a thick, dark border to complete the doorbell camera look
    ctx.lineWidth = size * 0.1;
    const bezelGradient = ctx.createLinearGradient(0, 0, size, size);
    bezelGradient.addColorStop(0, '#444');
    bezelGradient.addColorStop(0.5, '#111');
    bezelGradient.addColorStop(1, '#222');
    ctx.strokeStyle = bezelGradient;
    ctx.beginPath();
    ctx.arc(centerX, centerY, radius - ctx.lineWidth / 2, 0, Math.PI * 2);
    ctx.stroke();

    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 ‘Photo of Abandoned Sci-Fi Universe Captured from Doorbell Camera’ tool processes images to create a unique aesthetic reminiscent of sci-fi environments as if viewed through a vintage doorbell camera. This tool applies various visual effects, including fisheye distortion, desaturation, grain effects, color tints, and a vignette, to produce a stylized circular image. Users can customize the intensity of these effects to create distinctive artwork or atmospheric visuals suitable for creative projects, online sharing, or as backgrounds. Ideal for artists, photographers, or anyone looking to transform images into intriguing sci-fi themed artwork.

Leave a Reply

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