You can edit the below JavaScript code to customize the image tool.
function processImage(originalImg, primaryColorStr = "rgb(200,150,100)", secondaryColorStr = "rgb(150,100,80)", tintStrength = 0.6, bandStrength = 0.4, swirlStrength = 15, patternScale = 0.03) {
// Helper function to parse color strings (hex, rgb, named) to {r, g, b}
function parseColor(colorStr) {
if (typeof colorStr !== 'string' || !colorStr) {
// Default to black if colorStr is not a valid string or is empty
return { r: 0, g: 0, b: 0 };
}
// For robust color parsing, use a temporary canvas
const canvas = document.createElement('canvas');
canvas.width = 1;
canvas.height = 1;
// Use willReadFrequently for potential performance optimization if available
const ctx = canvas.getContext('2d', { willReadFrequently: true });
if (!ctx) { // Fallback in case context cannot be created
console.warn("Failed to create 2D context for color parsing.");
return { r:0, g:0, b:0 };
}
ctx.fillStyle = colorStr; // Assign the color string
ctx.fillRect(0, 0, 1, 1); // Draw a 1x1 pixel of this color
// Get the color data of this pixel. getImageData returns [R, G, B, A]
const [r, g, b] = ctx.getImageData(0, 0, 1, 1).data;
return { r, g, b };
}
const parsedPrimaryColor = parseColor(primaryColorStr);
const parsedSecondaryColor = parseColor(secondaryColorStr);
const canvas = document.createElement('canvas');
// Use willReadFrequently for potential performance optimization
const ctx = canvas.getContext('2d', { willReadFrequently: true });
if (!originalImg || !(originalImg.naturalWidth || originalImg.width) || !(originalImg.naturalHeight || originalImg.height)) {
// Return an empty or minimal canvas if image is invalid or not loaded
canvas.width = 100; // Default small size
canvas.height = 100;
ctx.fillStyle = 'gray';
ctx.fillRect(0,0,canvas.width,canvas.height);
ctx.fillStyle = 'black';
ctx.fillText("Invalid Image", 10, 50);
console.error("Original image is invalid, not loaded, or has zero dimensions.");
return canvas;
}
const width = originalImg.naturalWidth || originalImg.width;
const height = originalImg.naturalHeight || originalImg.height;
canvas.width = width;
canvas.height = height;
// Draw the original image to the canvas
ctx.drawImage(originalImg, 0, 0, width, height);
// --- Pass 1: Swirl Distortion ---
if (swirlStrength > 0 && patternScale > 0) { // Only run if effect is active
const sourceImageData = ctx.getImageData(0, 0, width, height);
const sourceData = sourceImageData.data;
const distortedImageData = ctx.createImageData(width, height);
const distortedData = distortedImageData.data;
for (let y = 0; y < height; y++) {
for (let x = 0; x < width; x++) {
// Complex sinusoidal displacement for a more "fluid" swirl
const angleX = x * patternScale * 1.5 + y * patternScale * 0.05;
const angleY = y * patternScale * 2.0 + x * patternScale * 0.1;
const offsetX = Math.sin(angleY) * swirlStrength +
Math.cos(angleX) * swirlStrength * 0.7; // Added 0.7 factor for variation
const offsetY = Math.cos(angleX) * swirlStrength +
Math.sin(angleY) * swirlStrength * 0.7; // Added 0.7 factor for variation
let srcX = x + offsetX;
let srcY = y + offsetY;
// Clamp coordinates to be within bounds and round them
srcX = Math.round(Math.max(0, Math.min(width - 1, srcX)));
srcY = Math.round(Math.max(0, Math.min(height - 1, srcY)));
const Nsrc = (srcY * width + srcX) * 4;
const Ndst = (y * width + x) * 4;
distortedData[Ndst] = sourceData[Nsrc];
distortedData[Ndst + 1] = sourceData[Nsrc + 1];
distortedData[Ndst + 2] = sourceData[Nsrc + 2];
distortedData[Ndst + 3] = sourceData[Nsrc + 3]; // Alpha
}
}
// Put the distorted image data back onto the canvas for the next pass
ctx.putImageData(distortedImageData, 0, 0);
}
// If swirlStrength is 0 or patternScale is 0, canvas still contains the original image.
// --- Pass 2: Color Tinting and Banding ---
// Get image data (which is now the distorted image, or original if swirl was skipped)
const currentImageData = ctx.getImageData(0, 0, width, height);
const data = currentImageData.data;
const effectiveTintStrength = Math.max(0, Math.min(1, tintStrength));
const effectiveBandStrength = Math.max(0, Math.min(1, bandStrength));
for (let i = 0; i < data.length; i += 4) {
const x = (i / 4) % width;
const y = Math.floor((i / 4) / width);
let r = data[i];
let g = data[i+1];
let b = data[i+2];
// 1. Apply primary color tint
if (effectiveTintStrength > 0) {
r = r * (1 - effectiveTintStrength) + parsedPrimaryColor.r * effectiveTintStrength;
g = g * (1 - effectiveTintStrength) + parsedPrimaryColor.g * effectiveTintStrength;
b = b * (1 - effectiveTintStrength) + parsedPrimaryColor.b * effectiveTintStrength;
}
// 2. Apply banding with secondary color
if (effectiveBandStrength > 0 && patternScale > 0) {
// A more complex band pattern, involving x and y for waviness & varied intensity
const bandNoiseVal1 = Math.sin(y * patternScale * 5 + x * patternScale * 0.3);
const bandNoiseVal2 = Math.cos(x * patternScale * 0.8 + y * patternScale * 0.1); // Different frequencies
// Combine and normalize to roughly 0-1 range
const bandNoise = (bandNoiseVal1 + bandNoiseVal2 * 0.5 + 1.5) / (1 + 0.5 + 1.5); // Sum of amplitudes + offset / Max possible value
const currentPixelBandStrength = bandNoise * effectiveBandStrength;
r = r * (1 - currentPixelBandStrength) + parsedSecondaryColor.r * currentPixelBandStrength;
g = g * (1 - currentPixelBandStrength) + parsedSecondaryColor.g * currentPixelBandStrength;
b = b * (1 - currentPixelBandStrength) + parsedSecondaryColor.b * currentPixelBandStrength;
}
// Clamp final colors to 0-255 range and assign
data[i] = Math.max(0, Math.min(255, Math.floor(r)));
data[i+1] = Math.max(0, Math.min(255, Math.floor(g)));
data[i+2] = Math.max(0, Math.min(255, Math.floor(b)));
// data[i+3] (alpha) remains unchanged from the (potentially distorted) source
}
// Put the final processed image data back
ctx.putImageData(currentImageData, 0, 0);
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 Image Gas Giant Atmosphere Filter Effect tool allows users to apply a unique filter effect to their images that mimics the appearance of gas giant atmospheres. By utilizing various parameters, users can introduce swirling distortions, color tints, and banding effects to create visually striking images reminiscent of planetary atmospheres. This tool can be particularly useful for artists, graphic designers, and hobbyists looking to enhance their digital artwork, create atmospheric backgrounds, or simply experiment with creative image transformations.