From a89b050e899df0c17a575aa5b5d5f7118bc048a1 Mon Sep 17 00:00:00 2001 From: Alexander Zinchuk Date: Fri, 8 Jul 2022 15:00:25 +0200 Subject: [PATCH] Composer: Select transparency fill color depending on brightness (#1939) --- src/util/colors.ts | 7 +++++++ src/util/imageResize.ts | 9 ++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/util/colors.ts b/src/util/colors.ts index 7d9a55849..8cbcd7c7f 100644 --- a/src/util/colors.ts +++ b/src/util/colors.ts @@ -171,6 +171,7 @@ export async function getAverageColor(url: string): Promise<[number, number, num // eslint-disable-next-line no-cond-assign while ((i += blockSize * 4) < length) { + if (data.data[i + 3] === 0) continue; // Ignore fully transparent pixels ++count; rgb[0] += data.data[i]; rgb[1] += data.data[i + 1]; @@ -184,6 +185,12 @@ export async function getAverageColor(url: string): Promise<[number, number, num return rgb; } +export function isDarkColor(rgbColor: [number, number, number]) { + const [r, g, b] = rgbColor; + const luma = 0.2126 * r + 0.7152 * g + 0.0722 * b; + return luma < 128; +} + // eslint-disable-next-line max-len // Function was adapted from https://github.com/telegramdesktop/tdesktop/blob/35ff621b5b52f7e3553fb0f990ea13ade7101b8e/Telegram/SourceFiles/data/data_wall_paper.cpp#L518 export function getPatternColor(rgbColor: [number, number, number]) { diff --git a/src/util/imageResize.ts b/src/util/imageResize.ts index 1800513bf..f6f04e073 100644 --- a/src/util/imageResize.ts +++ b/src/util/imageResize.ts @@ -1,3 +1,5 @@ +import { getAverageColor, isDarkColor } from './colors'; + export function scaleImage(image: string | Blob, ratio: number, outputType: string = 'image/png'): Promise { const url = image instanceof Blob ? URL.createObjectURL(image) : image; const img = new Image(); @@ -53,15 +55,20 @@ async function scale( if (bitmap.height !== height || bitmap.width !== width) { throw new Error('Image bitmap resize not supported!'); // FF93 added support for options, but not resize } + const averageColor = await getAverageColor(img.src); + const fillColor = isDarkColor(averageColor) ? '#fff' : '#000'; return await new Promise((res) => { const canvas = document.createElement('canvas'); canvas.width = bitmap.width; canvas.height = bitmap.height; + const ctx2D = canvas.getContext('2d')!; + ctx2D.fillStyle = fillColor; + ctx2D.fillRect(0, 0, canvas.width, canvas.height); const ctx = canvas.getContext('bitmaprenderer'); if (ctx) { ctx.transferFromImageBitmap(bitmap); } else { - canvas.getContext('2d')!.drawImage(bitmap, 0, 0); + ctx2D.drawImage(bitmap, 0, 0); } canvas.toBlob(res, outputType); });