You can edit the below JavaScript code to customize the image tool.
async function processImage(originalImg) {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
// Use naturalWidth/Height for HTMLImageElement, fallback to width/height for other sources like another canvas.
const imgWidth = originalImg.naturalWidth || originalImg.width;
const imgHeight = originalImg.naturalHeight || originalImg.height;
// If image dimensions are invalid (e.g., image not loaded yet), return an empty or minimal canvas.
if (imgWidth === 0 || imgHeight === 0) {
console.error("Image dimensions are 0. Ensure the image is loaded before processing.");
// Set a fallback small size for the canvas to avoid errors if it must be returned.
canvas.width = 1;
canvas.height = 1;
return canvas;
}
canvas.width = imgWidth;
canvas.height = imgHeight;
// 1. Apply global color/tone adjustments using CSS filters
// These values are chosen to approximate the "Konica Hexar AF" look:
// - contrast: Slightly punchy and clear.
// - saturate: Moderately saturated,Hexar is known for natural colors, not overly desaturated or oversaturated.
// A slight reduction can give a more filmic feel vs digital's default.
// - sepia: Adds a subtle warmth. It can also help in giving a slightly analogue feel to colors.
// - brightness: Minor adjustment to lift shadows slightly or compensate for contrast.
const filterSettings = {
contrast: 1.15, // 115% contrast
saturate: 0.95, // 95% saturation (slight reduction)
sepia: 0.10, // 10% sepia for warmth
brightness: 0.98 // 98% brightness (slight lift/density adjustment)
};
ctx.filter = `contrast(${filterSettings.contrast}) ` +
`saturate(${filterSettings.saturate}) ` +
`sepia(${filterSettings.sepia}) ` +
`brightness(${filterSettings.brightness})`;
ctx.drawImage(originalImg, 0, 0, canvas.width, canvas.height);
// Reset filter for subsequent operations like grain and vignette,
// which are applied directly to pixels or via canvas drawing methods.
ctx.filter = 'none';
// 2. Add Film Grain
// It's important to get imageData AFTER applying CSS filters,
// as the filters modify the pixels drawn onto the canvas.
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const data = imageData.data;
const grainAmount = 10; // Determines the intensity of the grain. Range of noise: [-grainAmount, +grainAmount]
for (let i = 0; i < data.length; i += 4) {
// Only apply grain to opaque pixels (alpha > 0)
if (data[i + 3] === 0) {
continue;
}
// Generate monochrome grain: a random value added equally to R, G, B
const grain = (Math.random() - 0.5) * grainAmount * 2; // noise in [-grainAmount, grainAmount]
data[i] = Math.max(0, Math.min(255, data[i] + grain));
data[i + 1] = Math.max(0, Math.min(255, data[i + 1] + grain));
data[i + 2] = Math.max(0, Math.min(255, data[i + 2] + grain));
// Alpha channel (data[i + 3]) remains unchanged
}
ctx.putImageData(imageData, 0, 0);
// 3. Add Vignette
const vignetteStrength = 0.35; // Max opacity of black at the very edges (0.0 to 1.0)
const vignetteStart = 0.5; // Percentage of radius where vignette begins to appear (0.0 to 1.0)
// e.g., 0.5 means central 50% of radius is clear, then fade begins.
const centerX = canvas.width / 2;
const centerY = canvas.height / 2;
// Calculate radius to cover image corners properly
const maxRadius = Math.hypot(centerX, centerY);
const gradient = ctx.createRadialGradient(
centerX, centerY, 0, // Inner circle for gradient starts at center point
centerX, centerY, maxRadius // Outer circle extends to corners
);
// Define gradient stops for the vignette effect
gradient.addColorStop(0, 'rgba(0,0,0,0)'); // Center is fully transparent
gradient.addColorStop(vignetteStart, 'rgba(0,0,0,0)'); // Stays transparent up to vignetteStart fraction of radius
gradient.addColorStop(1, `rgba(0,0,0,${vignetteStrength})`); // Darkens to vignetteStrength at the edges
// Apply the vignette by filling a rectangle with the radial gradient.
// Default globalCompositeOperation 'source-over' draws the gradient on top of the current canvas content.
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, canvas.width, canvas.height);
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 Konica Hexar AF Filter Effect Application allows users to apply a unique film-inspired aesthetic to their digital images. By simulating the classic look of the Konica Hexar AF camera, the tool enhances images with adjustments to contrast, saturation, sepia warmth, and brightness. Additionally, it adds a subtle film grain effect and a vignette that darkens the corners of the image, giving it an authentic analogue feel. This tool is ideal for photographers and digital artists looking to infuse their photos with a nostalgic, cinematic quality, or anyone wanting to enhance their images with a distinctive stylistic touch.