Please bookmark this page to avoid losing your image tool!

Image Projected Filter Effect Tool

(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, projectionOffsetX = 10, projectionOffsetY = 10, projectionColor = 'rgba(0,0,0,0.5)', projectionSkewX = 0.2, projectionSkewY = 0.0, projectionBlur = 5) {
    const W = originalImg.width;
    const H = originalImg.height;

    // Ensure numeric parameters are indeed numbers
    projectionOffsetX = Number(projectionOffsetX);
    projectionOffsetY = Number(projectionOffsetY);
    projectionSkewX = Number(projectionSkewX);
    projectionSkewY = Number(projectionSkewY);
    const blur = Math.max(0, Number(projectionBlur));

    // Calculate bounding box of the skewed shape (relative to its own (0,0) origin)
    // These are the x and y coordinates of the 4 vertices of the parallelogram
    // formed by skewing a WxH rectangle, using the transform:
    // x' = x + skewX * y
    // y' = y + skewY * x
    // Vertices of original rectangle: (0,0), (W,0), (W,H), (0,H)
    // Transformed vertices (order: TL, TR, BR, BL for clarity in comments):
    const proj_vertices_x = [
        0,                          // Top-left new X: (0*1 + 0*skewX) = 0
        W,                          // Top-right new X: (W*1 + 0*skewX) = W
        W + projectionSkewX * H,    // Bottom-right new X: (W*1 + H*skewX)
        projectionSkewX * H         // Bottom-left new X: (0*1 + H*skewX)
    ];
    const proj_vertices_y = [
        0,                          // Top-left new Y: (0*skewY + 0*1) = 0
        projectionSkewY * W,        // Top-right new Y: (W*skewY + 0*1)
        H + projectionSkewY * W,    // Bottom-right new Y: (W*skewY + H*1)
        H                           // Bottom-left new Y: (0*skewY + H*1)
    ];

    const min_proj_local_x = Math.min(...proj_vertices_x);
    const max_proj_local_x = Math.max(...proj_vertices_x);
    const min_proj_local_y = Math.min(...proj_vertices_y);
    const max_proj_local_y = Math.max(...proj_vertices_y);

    // Determine overall bounding box.
    // Consider a conceptual drawing area where the original image's top-left is at (0,0).
    // The projection's anchor (top-left before skew) is at (projectionOffsetX, projectionOffsetY)
    // relative to the image's top-left.
    
    // Bounding box of the projection including skew and blur, relative to image's (0,0)
    const projBox_minX_rel = projectionOffsetX + min_proj_local_x - blur;
    const projBox_minY_rel = projectionOffsetY + min_proj_local_y - blur;
    const projBox_maxX_rel = projectionOffsetX + max_proj_local_x + blur;
    const projBox_maxY_rel = projectionOffsetY + max_proj_local_y + blur;

    // Overall bounding box of all elements (image + projection) in the conceptual space
    const overall_minX = Math.min(0, projBox_minX_rel); // Image starts at 0
    const overall_minY = Math.min(0, projBox_minY_rel); // Image starts at 0
    const overall_maxX = Math.max(W, projBox_maxX_rel); // Image extends to W
    const overall_maxY = Math.max(H, projBox_maxY_rel); // Image extends to H

    const canvasWidth = overall_maxX - overall_minX;
    const canvasHeight = overall_maxY - overall_minY;

    // This offset translates all drawing from conceptual space to canvas space (where top-left is 0,0)
    const drawShiftX = -overall_minX;
    const drawShiftY = -overall_minY;

    const canvas = document.createElement('canvas');
    // Ensure canvas dimensions are at least 1x1 to avoid issues with 0-size canvases.
    canvas.width = Math.max(1, canvasWidth);
    canvas.height = Math.max(1, canvasHeight);
    const ctx = canvas.getContext('2d');

    // If original image has no dimensions, return the (potentially empty) canvas.
    if (W <= 0 || H <= 0) {
        return canvas;
    }
    
    // Final drawing positions on the output canvas
    // Original image's (0,0) from conceptual space is now (drawShiftX, drawShiftY)
    const finalImgDrawX = drawShiftX;
    const finalImgDrawY = drawShiftY;
    
    // Projection's anchor point on canvas
    const finalProjAnchorX = drawShiftX + projectionOffsetX;
    const finalProjAnchorY = drawShiftY + projectionOffsetY;

    // Create the colored projection shape (silhouette of originalImg filled with projectionColor)
    // This temporary canvas will hold the image's shape, filled with the projection color.
    const tempCanvas = document.createElement('canvas');
    tempCanvas.width = W;
    tempCanvas.height = H;
    // Note: { willReadFrequently: true } can be a hint for performance optimization,
    // but is not strictly necessary for correctness here.
    const tempCtx = tempCanvas.getContext('2d'/*, { willReadFrequently: true }*/); 
    
    tempCtx.drawImage(originalImg, 0, 0);
    tempCtx.globalCompositeOperation = 'source-in'; // Only draw where destination (originalImg) has opaque pixels
    tempCtx.fillStyle = projectionColor;
    tempCtx.fillRect(0, 0, W, H);
    tempCtx.globalCompositeOperation = 'source-over'; // Reset composite operation

    // --- Draw the projection ---
    ctx.save(); // Save current state (transform, filter, etc.)
    
    if (blur > 0) {
        ctx.filter = `blur(${blur}px)`;
    }
    
    // Translate to the intended top-left anchor of the projection before skewing
    ctx.translate(finalProjAnchorX, finalProjAnchorY);
    // Apply skew transform. This skews around the (0,0) of the current transform space,
    // which is (finalProjAnchorX, finalProjAnchorY) in canvas coordinates.
    // ctx.transform(m11, m12, m21, m22, dx, dy)
    // m11: horizontal scale, m12: vertical skew, m21: horizontal skew, m22: vertical scale
    ctx.transform(1, projectionSkewY, projectionSkewX, 1, 0, 0); 
    
    // Draw the pre-colored silhouette from tempCanvas. Its (0,0) aligns with the skewed origin.
    ctx.drawImage(tempCanvas, 0, 0);
    
    ctx.restore(); // Restore state (resets filter, transform)

    // --- Draw the original image on top ---
    ctx.drawImage(originalImg, finalImgDrawX, finalImgDrawY);

    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 Projected Filter Effect Tool allows users to create a visually appealing projection effect on images. By adjusting parameters such as offset, color, skew, and blur, users can manipulate how the image appears, producing striking visuals suitable for artistic projects, web design, or enhancing photographs. This tool is particularly useful for graphic designers, digital artists, and anyone looking to add a creative flair to their images through customizable projection effects.

Leave a Reply

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