Core function
const processedImagebase64 = new ImageFilter(originalImage) .changeBrightness(brightness) .changeContrast(contrast) .getResult();
Step1: Create a new Image
let originalImage = new Image(); async function updateOriginalImage(url: string) { try { originalImage = await urlToImageElement(url); } catch (error) { console.warn(error); } } function urlToImageElement(dataUrl: string) { return new Promise<HTMLImageElement>((resolve, reject) => { const img = new Image(); img.setAttribute('crossOrigin', 'anonymous'); img.src = dataUrl; img.onload = () => resolve(img); img.onerror = reject; }) }
Step2: Apply Filter
const processedImagebase64 = new ImageFilter(originalImage) .changeBrightness(brightness) .changeContrast(contrast) .getResult(); export class ImageFilter { imagedata: ImageData canvas: HTMLCanvasElement; ctx: CanvasRenderingContext2D | null; /** * Create a Image Filter instance * @param {HTMLImageElement} inputImage An Image Element was expected * @returns call getResult() to get the processed image in base64 format */ constructor(inputImage: HTMLImageElement) { this.canvas = document.createElement('canvas'); this.canvas.width = inputImage.width; this.canvas.height = inputImage.height; this.ctx = this.canvas.getContext('2d'); if (this.ctx) { this.ctx.drawImage(inputImage, 0, 0, this.canvas.width, this.canvas.height); this.imagedata = this.ctx.getImageData(0, 0, this.canvas.width, this.canvas.height); } else { throw Error("ImageFilter init failed: Can't get context of canvas"); } } /** * Get processed image in base64 format * @returns {string} success: processed image in base64 format * @returns {undefined} failed: return undefined */ getResult() { if (this.ctx) { this.ctx.putImageData(this.imagedata, 0, 0); return this.canvas.toDataURL(); } else { return undefined; } } /** * Change Brightness * @param {number} amount 0:dark, 1:original, 2:brigher * @returns {ImageFilter} imageFilter object will be returned */ changeBrightness(amount: number) { const data = this.imagedata.data; let adjustedAmount = amount; if (amount > 2) { adjustedAmount = 2; } if (amount < 0) { adjustedAmount = 0; } let r, g, b; for (let i = 0; i < data.length; i += 4) { r = data[i] * adjustedAmount; g = data[i + 1] * adjustedAmount; b = data[i + 2] * adjustedAmount; data[i] = r; data[i + 1] = g; data[i + 2] = b; } return this; } /** * Change Contrast * @param {number} amount 0:less, 1:original, 2:more * @returns {ImageFilter} imageFilter object will be returned */ changeContrast(amount: number) { const data = this.imagedata.data; let adjustedAmount = amount; if (amount > 2) { adjustedAmount = 2; } if (amount < 0) { adjustedAmount = 0; } let r, g, b; for (let i = 0; i < data.length; i += 4) { r = 128 + (data[i] - 128) * adjustedAmount; g = 128 + (data[i + 1] - 128) * adjustedAmount; b = 128 + (data[i + 2] - 128) * adjustedAmount; data[i] = r; data[i + 1] = g; data[i + 2] = b; } return this; } }
Step3: Download processed Image
async function downloadImage(base64: string, fileName: string) { let tmpLink = document.createElement('a'); tmpLink.download = fileName; tmpLink.href = base64; tmpLink.click(); }