Please bookmark this page to avoid losing your image tool!

Image Heart-Shaped Cropper

(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) {
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');

    const originalWidth = originalImg.naturalWidth || originalImg.width;
    const originalHeight = originalImg.naturalHeight || originalImg.height;

    if (originalWidth === 0 || originalHeight === 0) {
        // Return an empty or minimal canvas if image dimensions are invalid
        canvas.width = 1;
        canvas.height = 1;
        return canvas;
    }

    // Set canvas dimensions to match the original image
    canvas.width = originalWidth;
    canvas.height = originalHeight;

    const W = canvas.width;
    const H = canvas.height;

    // Heart path coordinates are based on a 200x200 reference grid.
    // Points for the SVG path: M100,175 C40,130 40,70 100,25 C160,70 160,130 100,175 Z
    // Min X: 40, Max X: 160 => Natural width of heart shape on grid: 120
    // Min Y: 25, Max Y: 175 => Natural height of heart shape on grid: 150
    const heartRefWidth = 200; // The path is defined within a 200x200 box
    const heartRefHeight = 200;

    // To preserve the heart's aspect ratio, scale it uniformly
    const scale = Math.min(W / heartRefWidth, H / heartRefHeight);

    // Effective size of the 200x200 reference box on canvas
    const scaledHeartBoxWidth = heartRefWidth * scale;
    const scaledHeartBoxHeight = heartRefHeight * scale;

    // Calculate offsets to center the heart's reference box on the canvas
    const offsetX = (W - scaledHeartBoxWidth) / 2;
    const offsetY = (H - scaledHeartBoxHeight) / 2;

    // Draw the heart path, scaled and offset
    ctx.beginPath();
    // M 100,175
    ctx.moveTo(offsetX + 100 * scale, offsetY + 175 * scale);
    // C 40,130 40,70 100,25
    ctx.bezierCurveTo(
        offsetX + 40 * scale, offsetY + 130 * scale,  // Control Point 1
        offsetX + 40 * scale, offsetY + 70 * scale,   // Control Point 2
        offsetX + 100 * scale, offsetY + 25 * scale   // End Point
    );
    // C 160,70 160,130 100,175
    ctx.bezierCurveTo(
        offsetX + 160 * scale, offsetY + 70 * scale,   // Control Point 1
        offsetX + 160 * scale, offsetY + 130 * scale,  // Control Point 2
        offsetX + 100 * scale, offsetY + 175 * scale   // End Point
    );
    ctx.closePath();

    // Set the heart path as the clipping region
    ctx.clip();

    // Determine the actual bounding box of the drawn heart on the canvas
    // (using natural extents of the heart shape: 120 wide, 150 tall, on the 200x200 grid)
    const heartActualScaledWidth = 120 * scale;
    const heartActualScaledHeight = 150 * scale;
    // Top-left corner of this bounding box relative to (offsetX, offsetY)
    const heartActualBoxOffsetX = 40 * scale; 
    const heartActualBoxOffsetY = 25 * scale;
    
    // Absolute coordinates of the heart's true bounding box on canvas
    const heartDrawBoxX = offsetX + heartActualBoxOffsetX;
    const heartDrawBoxY = offsetY + heartActualBoxOffsetY;
    const heartDrawBoxWidth = heartActualScaledWidth;
    const heartDrawBoxHeight = heartActualScaledHeight;

    // Calculate how to draw the image to cover the heart's bounding box ("object-fit: cover" behavior)
    const imgAspect = originalWidth / originalHeight;
    const heartBoxAspect = heartDrawBoxWidth / heartDrawBoxHeight; // Approx 120/150 = 4/5

    let drawX, drawY, drawWidth, drawHeight;

    if (imgAspect > heartBoxAspect) {
        // Image is wider or less tall than heart box relative to their aspect ratios; fit height, crop width
        drawHeight = heartDrawBoxHeight;
        drawWidth = drawHeight * imgAspect;
        drawX = heartDrawBoxX - (drawWidth - heartDrawBoxWidth) / 2; // Center horizontally
        drawY = heartDrawBoxY;
    } else {
        // Image is taller or less wide than heart box; fit width, crop height
        drawWidth = heartDrawBoxWidth;
        drawHeight = drawWidth / imgAspect;
        drawX = heartDrawBoxX;
        drawY = heartDrawBoxY - (drawHeight - heartDrawBoxHeight) / 2; // Center vertically
    }

    // Draw the original image, scaled and positioned to cover the heart shape
    // The clipping path will ensure only the heart-shaped part is visible
    ctx.drawImage(originalImg, drawX, drawY, drawWidth, drawHeight);

    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 Heart-Shaped Cropper is a tool designed to transform standard images into a visually striking heart shape. It allows users to upload an image and automatically crop it into a heart outline, making it perfect for use in creative projects such as personalized greeting cards, social media graphics, or romantic photo gifts. This tool ensures that the key elements of the image are preserved within the heart shape, providing beautifully cropped images that add a unique touch to any visual content.

Leave a Reply

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