Please bookmark this page to avoid losing your image tool!

Apple Major 2 Image Effect Generator

(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, pixelSize = "4", dithering = "1", scanlineOpacity = "0.15") {
    // Treat "Apple Major 2" as an "Apple II" (Apple 2) retro vintage computer effect,
    // reducing the image colors to the classic 6-color Apple II Hi-Res palette,
    // downscaling for pixelation, applying optional Floyd-Steinberg dithering, 
    // and rendering an authentic CRT scanline effect.
    
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');

    canvas.width = originalImg.width;
    canvas.height = originalImg.height;

    const pSize = Math.max(1, parseInt(pixelSize));
    const useDither = parseInt(dithering) !== 0;
    const sOpacity = parseFloat(scanlineOpacity);

    // Calculate downscaled dimensions for pixelation
    const smWidth = Math.max(1, Math.floor(canvas.width / pSize));
    const smHeight = Math.max(1, Math.floor(canvas.height / pSize));

    const tempCanvas = document.createElement('canvas');
    tempCanvas.width = smWidth;
    tempCanvas.height = smHeight;
    const tempCtx = tempCanvas.getContext('2d');

    tempCtx.drawImage(originalImg, 0, 0, smWidth, smHeight);

    // Fetch pixels for manipulation
    const imgData = tempCtx.getImageData(0, 0, smWidth, smHeight);
    const data = imgData.data;

    // Classic Apple II Hi-Res Palette
    const palette = [
        [0, 0, 0],       // Black
        [255, 255, 255], // White
        [20, 223, 20],   // Green
        [202, 36, 202],  // Purple
        [224, 64, 0],    // Orange
        [57, 178, 233]   // Blue
    ];

    // Euclid distance function to locate the closest palette color
    function closestColor(r, g, b) {
        let minDistance = Infinity;
        let closest = palette[0];
        for (let i = 0; i < palette.length; i++) {
            const dr = r - palette[i][0];
            const dg = g - palette[i][1];
            const db = b - palette[i][2];
            const dist = dr * dr + dg * dg + db * db;
            if (dist < minDistance) {
                minDistance = dist;
                closest = palette[i];
            }
        }
        return closest;
    }

    const getIdx = (x, y) => (y * smWidth + x) * 4;

    for (let y = 0; y < smHeight; y++) {
        for (let x = 0; x < smWidth; x++) {
            const idx = getIdx(x, y);
            const oldR = data[idx];
            const oldG = data[idx+1];
            const oldB = data[idx+2];

            // Quantize color to Apple 2 Palette
            const newC = closestColor(oldR, oldG, oldB);
            data[idx] = newC[0];
            data[idx+1] = newC[1];
            data[idx+2] = newC[2];

            // Apply Floyd-Steinberg error diffusion dithering to retain visual nuance
            if (useDither) {
                const errR = oldR - newC[0];
                const errG = oldG - newC[1];
                const errB = oldB - newC[2];

                const distributeError = (dx, dy, weight) => {
                    const nx = x + dx;
                    const ny = y + dy;
                    if (nx >= 0 && nx < smWidth && ny >= 0 && ny < smHeight) {
                        const nIdx = getIdx(nx, ny);
                        data[nIdx] = Math.min(255, Math.max(0, data[nIdx] + errR * weight));
                        data[nIdx+1] = Math.min(255, Math.max(0, data[nIdx+1] + errG * weight));
                        data[nIdx+2] = Math.min(255, Math.max(0, data[nIdx+2] + errB * weight));
                    }
                };

                distributeError(1, 0, 7/16);
                distributeError(-1, 1, 3/16);
                distributeError(0, 1, 5/16);
                distributeError(1, 1, 1/16);
            }
        }
    }

    tempCtx.putImageData(imgData, 0, 0);

    // Disable image smoothing for sharp, crisp retro pixels when scaling up
    ctx.imageSmoothingEnabled = false;
    ctx.drawImage(tempCanvas, 0, 0, canvas.width, canvas.height);

    // Overlay CRT scanlines
    if (sOpacity > 0 && pSize > 1) {
        ctx.fillStyle = `rgba(0, 0, 0, ${sOpacity})`;
        const lineH = Math.max(1, Math.floor(pSize * 0.25));
        for (let y = 0; y < canvas.height; y += pSize) {
            ctx.fillRect(0, y, canvas.width, lineH);
        }
    }

    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 Apple Major 2 Image Effect Generator is a specialized tool designed to transform modern images into a retro, vintage aesthetic reminiscent of classic Apple II computing. The tool applies a specific 6-color high-resolution palette, implements pixelation through downscaling, and offers options for Floyd-Steinberg dithering to add visual texture. Additionally, it can overlay authentic CRT-style scanlines to complete the old-school computer monitor look. This tool is ideal for digital artists, game developers, or anyone looking to create nostalgic, lo-fi graphics for social media, web design, or retro-themed creative projects.

Leave a Reply

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