You can edit the below JavaScript code to customize the image tool.
/**
* Interprets the input image as a musical piece, generating a visual representation.
* This function overlays a waveform and musical notes onto the original image.
* The waveform's shape is algorithmically derived from the average brightness of each vertical
* column of pixels in the image. Brighter areas result in higher wave peaks.
* Additionally, musical note symbols are scattered across the image, with their size
* dynamically adjusted based on the brightness of the area they occupy.
*
* @param {HTMLImageElement} originalImg The original image object to process.
* @param {string} [waveColor='rgba(255, 255, 255, 0.8)'] The color of the waveform overlay in a CSS format (e.g., 'white', '#FFF', 'rgba(255,255,255,0.8)').
* @param {number} [waveHeightMultiplier=0.25] A number controlling the maximum amplitude of the wave, as a fraction of the total image height. 0.5 would mean the wave can span half the image height.
* @param {string} [noteColor='rgba(0, 0, 0, 0.7)'] The color of the musical note symbols.
* @param {number} [noteDensity=0.0001] Determines how many notes are scattered on the image. A value of 0.0001 means approximately 1 note per 10,000 pixels.
* @param {number} [noteSize=20] The base size of the musical notes in pixels. The actual size will vary based on image brightness.
* @returns {Promise<HTMLCanvasElement>} A promise that resolves with a new canvas element containing the "AI music" visualization.
*/
async function processImage(originalImg, waveColor = 'rgba(255, 255, 255, 0.8)', waveHeightMultiplier = 0.25, noteColor = 'rgba(0, 0, 0, 0.7)', noteDensity = 0.0001, noteSize = 20) {
// 1. Setup Canvas
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.width = originalImg.naturalWidth;
canvas.height = originalImg.naturalHeight;
// Draw the original image as the background
ctx.drawImage(originalImg, 0, 0);
// 2. Analyze Image Data
// For analysis, get pixel data from a temporary canvas to not read from the one we're drawing on.
// { willReadFrequently: true } is a performance hint for the browser.
const tempCanvas = document.createElement('canvas');
const tempCtx = tempCanvas.getContext('2d', { willReadFrequently: true });
tempCanvas.width = canvas.width;
tempCanvas.height = canvas.height;
tempCtx.drawImage(originalImg, 0, 0);
const imageData = tempCtx.getImageData(0, 0, canvas.width, canvas.height);
const data = imageData.data;
// 3. Generate and Draw Waveform
const wavePoints = [];
const centerY = canvas.height / 2;
const maxAmplitude = canvas.height * waveHeightMultiplier;
for (let x = 0; x < canvas.width; x++) {
let columnBrightnessSum = 0;
for (let y = 0; y < canvas.height; y++) {
const index = (y * canvas.width + x) * 4; // R, G, B, A
const r = data[index];
const g = data[index + 1];
const b = data[index + 2];
// Use the luminosity formula for a more accurate perceived brightness
const brightness = (0.299 * r + 0.587 * g + 0.114 * b) / 255; // Normalize to 0-1
columnBrightnessSum += brightness;
}
const avgBrightness = columnBrightnessSum / canvas.height;
// Map brightness (0 to 1) to a wave amplitude. We use (brightness - 0.5) to let the wave go both up and down from the center.
const amplitude = (avgBrightness - 0.5) * 2 * maxAmplitude;
wavePoints.push({ x: x, y: centerY - amplitude });
}
// Draw a smooth curve through the calculated points for an organic look
ctx.strokeStyle = waveColor;
ctx.lineWidth = Math.max(1, canvas.width / 500); // Scale line width with image size
ctx.shadowColor = 'rgba(0, 0, 0, 0.5)';
ctx.shadowBlur = 5;
ctx.beginPath();
ctx.moveTo(wavePoints[0].x, wavePoints[0].y);
for (let i = 1; i < wavePoints.length - 1; i++) {
// Use quadratic curve for smoothing, using midpoints as end-points and actual points as controls
const xc = (wavePoints[i].x + wavePoints[i + 1].x) / 2;
const yc = (wavePoints[i].y + wavePoints[i + 1].y) / 2;
ctx.quadraticCurveTo(wavePoints[i].x, wavePoints[i].y, xc, yc);
}
// Connect to the very last point
ctx.lineTo(wavePoints[wavePoints.length - 1].x, wavePoints[wavePoints.length - 1].y);
ctx.stroke();
// Reset shadow for subsequent drawings
ctx.shadowColor = 'transparent';
ctx.shadowBlur = 0;
// 4. Generate and Draw Musical Notes
const musicalNotes = ['♫', '♪', '♬', '♭', '♮', '♯', '𝄞', '𝄢'];
const numNotes = Math.floor(canvas.width * canvas.height * noteDensity);
ctx.fillStyle = noteColor;
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
for (let i = 0; i < numNotes; i++) {
const x = Math.random() * canvas.width;
const y = Math.random() * canvas.height;
// Get brightness at the note's position to influence its size
const pixelIndex = (Math.floor(y) * canvas.width + Math.floor(x)) * 4;
const r = data[pixelIndex];
const g = data[pixelIndex + 1];
const b = data[pixelIndex + 2];
const brightness = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
// Brighter areas get slightly larger notes
const currentNoteSize = noteSize * (0.5 + brightness);
const note = musicalNotes[Math.floor(Math.random() * musicalNotes.length)];
ctx.font = `${currentNoteSize}px Arial`; // Use a standard web-safe font
// Save context state to apply transformations locally
ctx.save();
ctx.translate(x, y);
// Add a slight random rotation for a more dynamic, less uniform feel
ctx.rotate((Math.random() - 0.5) * 0.5); // Rotate up to ~14 degrees in either direction
ctx.fillText(note, 0, 0);
ctx.restore(); // Restore context to its previous state
}
return canvas;
}
Free Image Tool Creator
Can't find the image tool you're looking for? Create one based on your own needs now!
The AI Music Image Generator is a creative tool that interprets input images as musical compositions, producing a visually dynamic representation. It overlays a waveform on the original image, with the waveform’s shape reflecting the average brightness of vertical columns of pixels, resulting in higher peaks in brighter areas. Additionally, various musical note symbols are scattered throughout the image, with their sizes adjusted based on local brightness. This tool can be used for artistic projects, promotional materials, or simply for fun, making it suitable for musicians, artists, and anyone interested in visually merging music and imagery.