You can edit the below JavaScript code to customize the image tool.
/**
* Applies a stylistic filter to an image based on musical characteristics.
*
* @param {Image} originalImg The original javascript Image object.
* @param {string} mood The mood of the music ('energetic', 'happy', 'sad', 'calm', 'angry'). Determines the color palette.
* @param {number} tempo The tempo of the music in BPM (e.g., 60-180). Controls textural frequency.
* @param {number} intensity The intensity/volume of the music (0.0 to 1.0). Controls the overall effect strength.
* @returns {HTMLCanvasElement} A new canvas element with the stylized image.
*/
function processImage(originalImg, mood = 'energetic', tempo = 120, intensity = 0.7) {
// 1. Setup Canvas
const canvas = document.createElement('canvas');
// The { willReadFrequently: true } option can improve performance on some browsers for getImageData/putImageData.
const ctx = canvas.getContext('2d', {
willReadFrequently: true
});
canvas.width = originalImg.naturalWidth;
canvas.height = originalImg.naturalHeight;
// Draw the original image to the canvas to get its pixel data
ctx.drawImage(originalImg, 0, 0);
// Get the pixel data from the canvas
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const data = imageData.data;
const width = canvas.width;
const height = canvas.height;
// 2. Define effect parameters based on function inputs
const clampedIntensity = Math.max(0, Math.min(1, intensity));
let overlayColor = [0, 0, 0];
let saturationChange = 0;
let brightnessChange = 0;
let moodNoiseMultiplier = 1;
// Set color and mood parameters based on the 'mood' string
switch (mood) {
case 'happy':
overlayColor = [255, 220, 50]; // Bright Yellow
saturationChange = 0.25 * clampedIntensity;
brightnessChange = 20 * clampedIntensity;
break;
case 'sad':
overlayColor = [50, 80, 150]; // Dark Blue/Gray
saturationChange = -0.6 * clampedIntensity;
brightnessChange = -15 * clampedIntensity;
break;
case 'calm':
overlayColor = [100, 150, 220]; // Soft Blue
saturationChange = -0.2 * clampedIntensity;
brightnessChange = 5 * clampedIntensity;
moodNoiseMultiplier = 0.3; // Less noise for a calmer feel
break;
case 'angry':
overlayColor = [200, 40, 40]; // Red
saturationChange = 0.4 * clampedIntensity;
brightnessChange = -10 * clampedIntensity;
moodNoiseMultiplier = 2.5; // More noise/grain for a harsher feel
break;
case 'energetic':
default:
overlayColor = [255, 180, 0]; // Orange/Yellow
saturationChange = 0.3 * clampedIntensity;
brightnessChange = 10 * clampedIntensity;
break;
}
const overlayAlpha = 0.05 + 0.25 * clampedIntensity; // A subtle color overlay
const noiseAmount = 30 * clampedIntensity * moodNoiseMultiplier;
// Tempo controls the "period" of the wave pattern. Slower tempo = larger period (broader waves).
const basePeriod = 300;
const period = Math.max(20, basePeriod - tempo);
const waveAmplitude = 15 * clampedIntensity;
// 3. Process every pixel in a loop
for (let i = 0; i < data.length; i += 4) {
let r = data[i];
let g = data[i + 1];
let b = data[i + 2];
// --- Step A: Mood-based color correction ---
// Adjust Saturation using luminance approximation for speed
if (saturationChange !== 0) {
const lum = 0.299 * r + 0.587 * g + 0.114 * b;
const satFactor = 1 + saturationChange;
r = lum + satFactor * (r - lum);
g = lum + satFactor * (g - lum);
b = lum + satFactor * (b - lum);
}
// Adjust Brightness
r += brightnessChange;
g += brightnessChange;
b += brightnessChange;
// Apply Color Overlay
r = r * (1 - overlayAlpha) + overlayColor[0] * overlayAlpha;
g = g * (1 - overlayAlpha) + overlayColor[1] * overlayAlpha;
b = b * (1 - overlayAlpha) + overlayColor[2] * overlayAlpha;
// --- Step B: Tempo/Intensity based texture ---
if (waveAmplitude > 0 || noiseAmount > 0) {
const x = (i / 4) % width;
const y = Math.floor((i / 4) / width);
// Add Wave "Ripples" as a brightness offset based on sine waves
const waveX = Math.sin(y / period * 2 * Math.PI);
const waveY = Math.cos(x / period * 2 * Math.PI);
const waveOffset = waveAmplitude * (waveX + waveY);
r += waveOffset;
g += waveOffset;
b += waveOffset;
// Add Noise
const noise = (Math.random() - 0.5) * noiseAmount;
r += noise;
g += noise;
b += noise;
}
// --- Step C: Clamp values and update pixel data ---
data[i] = Math.max(0, Math.min(255, r));
data[i + 1] = Math.max(0, Math.min(255, g));
data[i + 2] = Math.max(0, Math.min(255, b));
}
// 4. Put the modified pixel data back onto the canvas
ctx.putImageData(imageData, 0, 0);
// For 'calm', add a final blur effect for a softer look
if (mood === 'calm') {
// A new canvas is needed because canvas filters apply to drawing operations, not existing content.
const finalCanvas = document.createElement('canvas');
finalCanvas.width = canvas.width;
finalCanvas.height = canvas.height;
const finalCtx = finalCanvas.getContext('2d');
const blurAmount = clampedIntensity * 2; // Blur up to 2px
finalCtx.filter = `blur(${blurAmount}px)`;
finalCtx.drawImage(canvas, 0, 0); // Draw the pixel-processed canvas onto the new, filtered canvas
return finalCanvas;
}
// 5. Return the final canvas
return canvas;
}
Free Image Tool Creator
Can't find the image tool you're looking for? Create one based on your own needs now!
Image Style Transfer from Music is a creative tool that allows users to apply stylistic filters to images based on the characteristics of music. By inputting the mood, tempo, and intensity of a chosen piece of music, users can transform their images to reflect various emotional tones, such as energetic, happy, sad, calm, or angry. This can be useful for artists and designers looking to create visually expressive artwork, enhance social media posts, or develop unique visuals for music projects. The tool adjusts colors, brightness, and texture according to the musical parameters, resulting in a personalized and dynamic interpretation of the original image.