Please bookmark this page to avoid losing your image tool!

Image Album Cover Template Creator

(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,
    outputSize = 600,
    titleText = "ALBUM TITLE",
    artistText = "ARTIST NAME",
    textColor = "white",
    fontFamily = "Arial Black, Gadget, sans-serif",
    titleFontSizeRatio = 0.08,
    artistFontSizeRatio = 0.05,
    textBlockPosition = "bottom", // "top", "bottom", "none"
    textAlign = "center", // "left", "center", "right"
    textPaddingRatio = 0.05, // Padding for text block from canvas edges & PA label margin
    textShadowEnabled = 1, // 0 for false, 1 for true
    showParentalAdvisory = 0, // 0 for false, 1 for true
    parentalAdvisoryType = "explicit_content", // "explicit_content", "explicit_lyrics"
    parentalAdvisoryPosition = "bottom-right", // "bottom-right", "bottom-left", "top-right", "top-left"
    parentalAdvisoryWidthRatio = 0.3, // Width of PA label as ratio of outputSize
    parentalAdvisoryFontFamily = "Impact, Arial Black, sans-serif"
) {
    const canvas = document.createElement('canvas');
    canvas.width = outputSize;
    canvas.height = outputSize;
    const ctx = canvas.getContext('2d');

    // 1. Draw the image (cover mode)
    const imgWidth = originalImg.naturalWidth || originalImg.width;
    const imgHeight = originalImg.naturalHeight || originalImg.height;
    
    if (imgWidth === 0 || imgHeight === 0) {
        // Draw a placeholder if image is not loaded or invalid
        ctx.fillStyle = '#cccccc';
        ctx.fillRect(0, 0, outputSize, outputSize);
        ctx.fillStyle = '#333333';
        ctx.textAlign = 'center';
        ctx.textBaseline = 'middle';
        ctx.font = `${outputSize * 0.05}px Arial`;
        ctx.fillText("Image Error", outputSize / 2, outputSize / 2 - outputSize * 0.03);
        ctx.fillText("(No image loaded or image is empty)", outputSize / 2, outputSize / 2 + outputSize * 0.03);
        return canvas;
    }

    const canvasAspect = 1; // outputSize / outputSize (square)
    const imgAspect = imgWidth / imgHeight;

    let sx = 0, sy = 0, sWidth = imgWidth, sHeight = imgHeight;

    if (imgAspect > canvasAspect) { // Image is wider than target aspect (e.g., landscape image on square canvas)
        sWidth = imgHeight * canvasAspect; // Crop width
        sx = (imgWidth - sWidth) / 2;     // Center horizontally
    } else if (imgAspect < canvasAspect) { // Image is taller than target aspect (e.g., portrait image on square canvas)
        sHeight = imgWidth / canvasAspect; // Crop height
        sy = (imgHeight - sHeight) / 2;    // Center vertically
    }
    // If imgAspect === canvasAspect, sx, sy, sWidth, sHeight are already correct for full image.
    
    ctx.drawImage(originalImg, sx, sy, sWidth, sHeight, 0, 0, outputSize, outputSize);

    // 2. Draw Text (Title and Artist)
    const cleanTitleText = titleText.trim();
    const cleanArtistText = artistText.trim();

    if (textBlockPosition !== "none" && (cleanTitleText || cleanArtistText)) {
        const titleFontSize = outputSize * titleFontSizeRatio;
        const artistFontSize = outputSize * artistFontSizeRatio;
        const padding = outputSize * textPaddingRatio;
        // Min 2px or 1.5% of outputSize for line spacing.
        const mainTextLineSpacing = Math.max(2, outputSize * 0.015); 

        if (textShadowEnabled === 1) {
            ctx.shadowColor = 'rgba(0,0,0,0.7)';
            // Min 3px blur or 1% of outputSize for shadow blur.
            ctx.shadowBlur = Math.max(3, outputSize * 0.01); 
            // Min 1px offset or 0.3% of outputSize for shadow offset.
            ctx.shadowOffsetX = Math.max(1, outputSize * 0.003); 
            ctx.shadowOffsetY = Math.max(1, outputSize * 0.003);
        }

        ctx.fillStyle = textColor;
        
        let textX;
        if (textAlign === "left") {
            ctx.textAlign = "left";
            textX = padding;
        } else if (textAlign === "right") {
            ctx.textAlign = "right";
            textX = outputSize - padding;
        } else { // Default to center
            ctx.textAlign = "center";
            textX = outputSize / 2;
        }

        if (textBlockPosition === "bottom") {
            ctx.textBaseline = 'bottom';
            let currentY = outputSize - padding;
            if (cleanArtistText) {
                ctx.font = `${artistFontSize}px ${fontFamily}`;
                ctx.fillText(cleanArtistText, textX, currentY);
                currentY -= (artistFontSize + mainTextLineSpacing);
            }
            if (cleanTitleText) {
                ctx.font = `${titleFontSize}px ${fontFamily}`;
                ctx.fillText(cleanTitleText, textX, currentY);
            }
        } else if (textBlockPosition === "top") {
            ctx.textBaseline = 'top';
            let currentY = padding;
            if (cleanTitleText) {
                ctx.font = `${titleFontSize}px ${fontFamily}`;
                ctx.fillText(cleanTitleText, textX, currentY);
                currentY += (titleFontSize + mainTextLineSpacing);
            }
            if (cleanArtistText) {
                ctx.font = `${artistFontSize}px ${fontFamily}`;
                ctx.fillText(cleanArtistText, textX, currentY);
            }
        }

        // Clear shadow for subsequent drawing operations
        if (textShadowEnabled === 1) {
            ctx.shadowColor = 'transparent'; // Or 'rgba(0,0,0,0)'
            ctx.shadowBlur = 0;
            ctx.shadowOffsetX = 0;
            ctx.shadowOffsetY = 0;
        }
    }

    // 3. Draw Parental Advisory Label
    if (showParentalAdvisory === 1) {
        const paLabelWidth = outputSize * parentalAdvisoryWidthRatio;
        // Standard-ish aspect ratio is ~2.6:1 for the PA label.
        const paLabelHeight = paLabelWidth / 2.6; 
        // Use textPaddingRatio for PA label's margin from canvas edge.
        const paLabelMarginFromEdge = outputSize * textPaddingRatio; 

        let palX, palY; // Top-left corner of the PA label
        if (parentalAdvisoryPosition === "bottom-left") {
            palX = paLabelMarginFromEdge;
            palY = outputSize - paLabelHeight - paLabelMarginFromEdge;
        } else if (parentalAdvisoryPosition === "top-left") {
            palX = paLabelMarginFromEdge;
            palY = paLabelMarginFromEdge;
        } else if (parentalAdvisoryPosition === "top-right") {
            palX = outputSize - paLabelWidth - paLabelMarginFromEdge;
            palY = paLabelMarginFromEdge;
        } else { // Default to "bottom-right"
            palX = outputSize - paLabelWidth - paLabelMarginFromEdge;
            palY = outputSize - paLabelHeight - paLabelMarginFromEdge;
        }

        // Draw black background for PA label
        ctx.fillStyle = "black";
        ctx.fillRect(palX, palY, paLabelWidth, paLabelHeight);

        // PA Text
        ctx.fillStyle = "white";
        ctx.textAlign = "center";
        ctx.textBaseline = "middle";

        const paTextTop = "PARENTAL ADVISORY";
        const paTextBottom = parentalAdvisoryType === "explicit_lyrics" ? "EXPLICIT LYRICS" : "EXPLICIT CONTENT";
        
        // Horizontal padding inside the PA label (e.g., 5% of label width on each side)
        const paLabelPaddingHorizontal = paLabelWidth * 0.05; 
        const paUsableTextWidth = paLabelWidth - 2 * paLabelPaddingHorizontal;

        // Top Text: PARENTAL ADVISORY
        // Target font size ~32% of label height for this line. Make it bold.
        let paFontSizeTop = paLabelHeight * 0.32; 
        ctx.font = `bold ${paFontSizeTop}px ${parentalAdvisoryFontFamily}`;
        let textMetricsTop = ctx.measureText(paTextTop);
        if (textMetricsTop.width > paUsableTextWidth) {
            paFontSizeTop *= (paUsableTextWidth / textMetricsTop.width);
            ctx.font = `bold ${paFontSizeTop}px ${parentalAdvisoryFontFamily}`;
        }
        // Position text in the top ~35% of the label's vertical space
        ctx.fillText(paTextTop, palX + paLabelWidth / 2, palY + paLabelHeight * 0.35);

        // Bottom Text: EXPLICIT CONTENT/LYRICS
        // Target font size ~28% of label height. Font choice determines boldness.
        let paFontSizeBottom = paLabelHeight * 0.28; 
        ctx.font = `${paFontSizeBottom}px ${parentalAdvisoryFontFamily}`;
        let textMetricsBottom = ctx.measureText(paTextBottom);
        if (textMetricsBottom.width > paUsableTextWidth) {
            paFontSizeBottom *= (paUsableTextWidth / textMetricsBottom.width);
            ctx.font = `${paFontSizeBottom}px ${parentalAdvisoryFontFamily}`;
        }
        // Position text in the bottom ~75% of the label's vertical space
        ctx.fillText(paTextBottom, palX + paLabelWidth / 2, palY + paLabelHeight * 0.75);
    }

    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 Album Cover Template Creator allows users to create customized album cover art by uploading an image and adding text elements for the album title and artist name. Users can specify output size, font styles, text colors, alignment, and the placement of a parental advisory label if necessary. This tool is ideal for musicians, graphic designers, or anyone looking to design unique album covers for music projects or promotional materials.

Leave a Reply

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