You can edit the below JavaScript code to customize the image tool.
function processImage(originalImg, brightnessThreshold = 220, starSizeMean = 6, starSizeStdDev = 2, numPoints = 5, color = "white", density = 0.1, scanStep = 3, innerRadiusRatio = 0.4) {
// Helper function to draw a star, defined within processImage to keep it self-contained
// cx, cy: center of the star
// spikes: number of points on the star
// outerRadius: radius of the star's outer points
// innerRadius: radius of the star's inner points (valleys)
// fillColor: color of the star
// initialRotation: rotation of the star in radians
function drawStar(ctx, cx, cy, spikes, outerRadius, innerRadius, fillColor, initialRotation = 0) {
ctx.save();
ctx.translate(cx, cy);
ctx.rotate(initialRotation);
ctx.beginPath();
// Start drawing from the top point (or rotated top point)
let rot = Math.PI / 2 * 3; // Angle to start at the top (pointing upwards)
for (let i = 0; i < spikes; i++) {
// Outer point
let currentOuterX = 0 + Math.cos(rot) * outerRadius;
let currentOuterY = 0 + Math.sin(rot) * outerRadius;
if (i === 0) {
ctx.moveTo(currentOuterX, currentOuterY);
} else {
ctx.lineTo(currentOuterX, currentOuterY);
}
rot += Math.PI / spikes; // Increment angle for the next inner point
// Inner point
let currentInnerX = 0 + Math.cos(rot) * innerRadius;
let currentInnerY = 0 + Math.sin(rot) * innerRadius;
ctx.lineTo(currentInnerX, currentInnerY);
rot += Math.PI / spikes; // Increment angle for the next outer point
}
ctx.closePath(); // Connects the last point to the first
ctx.fillStyle = fillColor;
ctx.fill();
ctx.restore(); // Restore translation and rotation state
}
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d', { willReadFrequently: true }); // willReadFrequently for getImageData performance
// Use naturalWidth/Height for intrinsic image dimensions
canvas.width = originalImg.naturalWidth || originalImg.width;
canvas.height = originalImg.naturalHeight || originalImg.height;
// Draw the original image onto the canvas
ctx.drawImage(originalImg, 0, 0, canvas.width, canvas.height);
// Get pixel data from the image
let imageData;
try {
imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
} catch (e) {
// This can happen due to cross-origin restrictions if the image is from another domain
// and the canvas becomes "tainted".
console.error("Error getting ImageData:", e);
// In this case, we cannot process pixels, so we return the canvas with just the original image.
return canvas;
}
const data = imageData.data;
const width = canvas.width;
const height = canvas.height;
// Validate and sanitize parameters to ensure they are within expected ranges/types
const sanBrightnessThreshold = Math.max(0, Math.min(255, Number(brightnessThreshold)));
const sanStarSizeMean = Math.max(1, Number(starSizeMean)); // Star diameter should be at least 1px
const sanStarSizeStdDev = Math.max(0, Number(starSizeStdDev));
// Ensure numPoints is an integer and at least 2 (2 points form a rhombus/diamond shape)
const sanNumPoints = Math.max(2, Math.floor(Number(numPoints)));
const sanColor = String(color); // Ensure color is a string
const sanDensity = Math.max(0, Math.min(1, Number(density))); // Density is a probability (0-1)
const sanScanStep = Math.max(1, Math.floor(Number(scanStep))); // Scan step must be at least 1
// Inner radius ratio should be between 0.01 (very spiky) and 1 (regular polygon like)
const sanInnerRadiusRatio = Math.max(0.01, Math.min(1, Number(innerRadiusRatio)));
// Iterate over pixels (with a step for performance) to find bright spots
for (let y = 0; y < height; y += sanScanStep) {
for (let x = 0; x < width; x += sanScanStep) {
// Calculate index for the current pixel in the ImageData array
// Each pixel is 4 values (R, G, B, A)
const idx = (y * width + x) * 4;
const r = data[idx];
const g = data[idx + 1];
const b = data[idx + 2];
// data[idx + 3] is alpha, not used for luminance calculation here
// Calculate luminance (brightness) of the pixel
const luminance = 0.299 * r + 0.587 * g + 0.114 * b;
// If pixel is bright enough and random chance passes, draw a star
if (luminance > sanBrightnessThreshold && Math.random() < sanDensity) {
// Determine star size with some randomness based on mean and std deviation
// This creates a uniform size variation around the mean
let sizeVariation = (Math.random() * 2 - 1) * sanStarSizeStdDev; // Range: [-stdDev, +stdDev]
let currentStarOuterDiameter = sanStarSizeMean + sizeVariation;
currentStarOuterDiameter = Math.max(1, currentStarOuterDiameter); // Ensure diameter is at least 1px
const outerRadius = currentStarOuterDiameter / 2;
const innerRadius = outerRadius * sanInnerRadiusRatio;
// Give each star a random rotation for a more natural look
const randomRotation = Math.random() * 2 * Math.PI;
// Draw the star centered at the current bright pixel (x, y)
drawStar(ctx, x, y, sanNumPoints, outerRadius, innerRadius, sanColor, randomRotation);
}
}
}
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 Stars Filter is an online tool that enhances images by overlaying star shapes at bright areas. Users can customize parameters such as brightness threshold, star size, number of points on each star, color, and density of the stars. This tool can be particularly useful for adding a creative touch to photographs, enhancing night sky images, or creating eye-catching graphics for social media and presentations. It allows users to quickly transform ordinary images into visually appealing artworks by simulating a starry effect.