Please bookmark this page to avoid losing your image tool!

Image Resizer Cropper Rotator Optimizer And GIF WebP Converter

(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,
    cropStr = "",           // "x,y,w,h" (empty string for full original image)
    resizeStr = "",         // "w,h" (empty string or "0,0" to bypass, specify one to keep aspect ratio)
    rotateDeg = 0,          // Rotation angle in standard degrees
    flipStr = "0,0",        // "flipHorizontal,flipVertical" (use 1 for true, 0 for false)
    filter = "none",        // CSS filter strings e.g., "grayscale(100%)", "blur(5px)"
    censorStr = "",         // "x,y,w,h,type" (type is "black" or "pixelate", absolute to final canvas)
    text = "",              // Overlay text, use \n for multiline
    overlayImgData = "",    // URL or Base64 string for an overlay/watermark image
    format = "image/webp",  // Target output format: "canvas", "webp", "jpeg", "png", "gif"
    quality = 0.92          // Output quality for JPEG/WebP compression (0.0 to 1.0)
) {
    // 1. Process Dimensions & Crop
    let sx = 0, sy = 0;
    let sw = originalImg.naturalWidth || originalImg.width;
    let sh = originalImg.naturalHeight || originalImg.height;

    if (cropStr && cropStr.trim() !== "") {
        const cParts = cropStr.split(',').map(Number);
        if (cParts.length >= 4) {
            sx = cParts[0];
            sy = cParts[1];
            sw = cParts[2];
            sh = cParts[3];
        }
    }
    
    // Bounds check to avoid invalid extract regions
    const nw = originalImg.naturalWidth || originalImg.width;
    const nh = originalImg.naturalHeight || originalImg.height;
    sw = Math.min(sw, nw - sx);
    sh = Math.min(sh, nh - sy);

    // 2. Process Resize
    let rw = sw, rh = sh;
    if (resizeStr && resizeStr.trim() !== "") {
        const rParts = resizeStr.split(',').map(Number);
        if (rParts.length >= 2) {
            const tw = rParts[0];
            const th = rParts[1];
            if (tw > 0 && th > 0) {
                rw = tw; rh = th;
            } else if (tw > 0) {
                rw = tw; rh = (tw / sw) * sh;
            } else if (th > 0) {
                rh = th; rw = (th / sh) * sw;
            }
        }
    }

    // 3. Process Rotation Canvas Bounds
    const rad = (Number(rotateDeg) || 0) * (Math.PI / 180);
    const absCos = Math.abs(Math.cos(rad));
    const absSin = Math.abs(Math.sin(rad));
    const finalW = (rw * absCos) + (rh * absSin);
    const finalH = (rw * absSin) + (rh * absCos);

    // Setup Canvas
    const canvas = document.createElement('canvas');
    canvas.width = finalW;
    canvas.height = finalH;
    const ctx = canvas.getContext('2d');

    // Parse Output format
    let outMime = format.toLowerCase().trim();
    if (outMime === "jpg") outMime = "image/jpeg";
    else if (!outMime.startsWith("image/") && outMime !== "canvas") {
        outMime = "image/" + outMime;
    }

    // Fill white background for JPEG exports to prevent transparent areas becoming black
    if (outMime === "image/jpeg") {
        ctx.fillStyle = "white";
        ctx.fillRect(0, 0, finalW, finalH);
    }

    // 4. Process Flips / Reverse
    let flipH = 1, flipV = 1;
    if (flipStr && flipStr.trim() !== "") {
        const fParts = flipStr.split(',').map(Number);
        if (fParts.length >= 2) {
            if (fParts[0] === 1) flipH = -1;
            if (fParts[1] === 1) flipV = -1;
        }
    }

    // Apply Transformation Matrix
    ctx.translate(finalW / 2, finalH / 2);
    ctx.rotate(rad);
    ctx.scale(flipH, flipV);

    // 5. Apply Optical Filters / Effects
    if (filter && filter !== "none") {
        ctx.filter = filter;
    }

    // Draw Source Image
    ctx.drawImage(originalImg, sx, sy, sw, sh, -rw / 2, -rh / 2, rw, rh);

    // Reset transformations for Censor, Overlay Image, and Text logic
    ctx.setTransform(1, 0, 0, 1, 0, 0);
    ctx.filter = "none";

    // 6. Censor Coordinates (Pixelate or Black block)
    if (censorStr && censorStr.trim() !== "") {
        const p = censorStr.split(',');
        if (p.length >= 4) {
            const cx = Number(p[0]), cy = Number(p[1]), cw = Number(p[2]), ch = Number(p[3]);
            const cType = p[4] ? p[4].trim().toLowerCase() : "black";
            
            if (cType === "pixelate") {
                // Extract Censor Area
                const tCanv = document.createElement('canvas');
                tCanv.width = cw; tCanv.height = ch;
                const tCtx = tCanv.getContext('2d');
                tCtx.drawImage(canvas, cx, cy, cw, ch, 0, 0, cw, ch);
                
                // Down-scale
                const shrinkRatio = 0.1; // 10% blocks
                const smW = Math.max(1, Math.floor(cw * shrinkRatio));
                const smH = Math.max(1, Math.floor(ch * shrinkRatio));
                
                const sCanv = document.createElement('canvas');
                sCanv.width = smW; sCanv.height = smH;
                sCanv.getContext('2d').drawImage(tCanv, 0, 0, cw, ch, 0, 0, smW, smH);
                
                // Up-scale sharply without anti-aliasing interpolation
                tCtx.imageSmoothingEnabled = false;
                tCtx.clearRect(0, 0, cw, ch);
                tCtx.drawImage(sCanv, 0, 0, smW, smH, 0, 0, cw, ch);
                
                // Overlay back onto main canvas
                ctx.drawImage(tCanv, 0, 0, cw, ch, cx, cy, cw, ch);
            } else {
                ctx.fillStyle = "black";
                ctx.fillRect(cx, cy, cw, ch);
            }
        }
    }

    // 7. Embed Add-on Image
    if (overlayImgData && overlayImgData.length > 5) {
        try {
            const oImg = new Image();
            oImg.crossOrigin = "anonymous";
            await new Promise((resolve, reject) => {
                oImg.onload = resolve;
                oImg.onerror = reject;
                oImg.src = overlayImgData;
            });
            // Defaulting placement to exact center
            ctx.drawImage(oImg, (finalW - oImg.width) / 2, (finalH - oImg.height) / 2);
        } catch (err) {
            console.error("Could not load overlay image.", err);
        }
    }

    // 8. Add Meme/Captions Overlay Text
    if (text && text.trim() !== "") {
        ctx.font = "bold 40px sans-serif";
        ctx.fillStyle = "white";
        ctx.strokeStyle = "black";
        ctx.lineWidth = 4;
        ctx.textAlign = "center";
        ctx.textBaseline = "middle";
        
        // Multi-line spacing alignment
        const parsedText = text.replace(/\\n/g, '\n');
        const lines = parsedText.split('\n');
        
        const lineHeight = 48;
        // Position chunk at the bottom relative to line count
        const startY = finalH - (lines.length * lineHeight) + (lineHeight / 2) - 20;

        lines.forEach((line, index) => {
            const y = startY + (index * lineHeight);
            ctx.strokeText(line, finalW / 2, y);
            ctx.fillText(line, finalW / 2, y);
        });
    }

    // 9. Output Processing / Converter Engine (to WebP, GIF, etc.)
    if (outMime === "canvas") {
        return canvas;
    }
    
    return new Promise((resolve, reject) => {
        canvas.toBlob((blob) => {
            if (!blob) return reject(new Error("Image conversion format processing failed."));
            const resImg = new Image();
            resImg.onload = () => resolve(resImg);
            resImg.onerror = reject;
            resImg.src = URL.createObjectURL(blob);
        }, outMime, Number(quality));
    });
}

Free Image Tool Creator

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

Description

This multi-purpose image processing tool allows you to crop, resize, rotate, and flip images with ease. It features advanced editing capabilities such as applying visual filters, censoring specific areas using pixelation or solid blocks, and adding text overlays or watermark images. Additionally, the tool serves as a converter and optimizer, allowing you to transform images into various formats like WebP, JPEG, PNG, or GIF while adjusting the output quality to balance file size and clarity. It is ideal for web developers, social media creators, and anyone needing to quickly prepare, protect, or brand digital images for different online platforms.

Leave a Reply

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