diff --git a/functions/api/image/tokens/[[index]].tsx b/functions/api/image/tokens/[[index]].tsx index 0e49c7d8f4..77010bbdd8 100644 --- a/functions/api/image/tokens/[[index]].tsx +++ b/functions/api/image/tokens/[[index]].tsx @@ -28,7 +28,7 @@ export const onRequest: PagesFunction = async ({ params, request }) => { return new Response('Token not found.', { status: 404 }) } - const [fontData, palette] = await Promise.all([getFont(), getColor(data.ogImage)]) + const [fontData, palette] = await Promise.all([getFont(), getColor(data.ogImage, true)]) const networkLogo = getNetworkLogoUrl(networkName.toUpperCase()) diff --git a/functions/utils/getColor.test.ts b/functions/utils/getColor.test.ts index c62e9f189a..2d1d2e13b3 100644 --- a/functions/utils/getColor.test.ts +++ b/functions/utils/getColor.test.ts @@ -19,6 +19,12 @@ test('should return the average color of a white PNG image', async () => { expect(color).toEqual([255, 255, 255]) }) +test('should return the average color of a white PNG image with whiteness dimmed', async () => { + const image = 'https://www.cac.cornell.edu/wiki/images/4/44/White_square.png' + const color = await getColor(image, true) + expect(color).toEqual(DEFAULT_COLOR) +}) + test('should return the average color of a black JPG image', async () => { const image = 'https://imageio.forbes.com/specials-images/imageserve/5ed6636cdd5d320006caf841/0x0.jpg?format=jpg&width=1200' diff --git a/functions/utils/getColor.ts b/functions/utils/getColor.ts index e1051a1776..8bccb991ea 100644 --- a/functions/utils/getColor.ts +++ b/functions/utils/getColor.ts @@ -4,7 +4,7 @@ import PNG from 'png-ts' import { DEFAULT_COLOR, predefinedTokenColors } from '../constants' -export default async function getColor(image: string | undefined) { +export default async function getColor(image: string | undefined, checkDistance = false) { if (!image) { return DEFAULT_COLOR } @@ -17,13 +17,13 @@ export default async function getColor(image: string | undefined) { const arrayBuffer = Buffer.from(buffer) const type = data.headers.get('content-type') ?? '' - return getAverageColor(arrayBuffer, type) + return getAverageColor(arrayBuffer, type, checkDistance) } catch (e) { return DEFAULT_COLOR } } -function getAverageColor(arrayBuffer: Uint8Array, type?: string) { +function getAverageColor(arrayBuffer: Uint8Array, type: string, checkDistance: boolean) { let pixels switch (type) { case 'image/png': { @@ -63,5 +63,13 @@ function getAverageColor(arrayBuffer: Uint8Array, type?: string) { g = Math.floor(g / (pixelCount - transparentPixels)) b = Math.floor(b / (pixelCount - transparentPixels)) + if (checkDistance) { + const distance = Math.sqrt(Math.pow(r - 255, 2) + Math.pow(g - 255, 2) + Math.pow(b - 255, 2)) + + if (distance < 50) { + return DEFAULT_COLOR + } + } + return [r, g, b] }