feat: improve HEIC, HEIF and JPEG XL browser support detection (#26122)

feat: improve heic, heif and jxl browser support detection
This commit is contained in:
Nicolò Maria Semprini
2026-03-04 03:41:51 +00:00
committed by GitHub
parent e4c24bdec8
commit 5532f669eb
+41 -6
View File
@@ -224,19 +224,54 @@ const supportedImageMimeTypes = new Set([
'image/webp', 'image/webp',
]); ]);
async function addSupportedMimeTypes(): Promise<void> {
const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent); // https://stackoverflow.com/a/23522755 const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent); // https://stackoverflow.com/a/23522755
if (isSafari) { if (isSafari) {
supportedImageMimeTypes.add('image/heic').add('image/heif'); const match = navigator.userAgent.match(/Version\/(\d+)/);
if (!match) {
return;
} }
function checkJxlSupport(): void { const majorVersion = Number.parseInt(match[1]);
const img = new Image(); const MIN_REQUIRED_VERSION = 17;
img.addEventListener('load', () => {
if (majorVersion >= MIN_REQUIRED_VERSION) {
supportedImageMimeTypes.add('image/jxl').add('image/heic').add('image/heif');
}
return;
}
if (globalThis.isSecureContext && typeof ImageDecoder !== 'undefined') {
const dynamicMimeTypes = [{ type: 'image/jxl' }, { type: 'image/heic', aliases: ['image/heif'] }];
for (const mime of dynamicMimeTypes) {
const isMimeTypeSupported = await ImageDecoder.isTypeSupported(mime.type);
if (isMimeTypeSupported) {
for (const mimeType of [mime.type, ...(mime.aliases || [])]) {
supportedImageMimeTypes.add(mimeType);
}
}
}
return;
}
const jxlImg = new Image();
jxlImg.addEventListener('load', () => {
supportedImageMimeTypes.add('image/jxl'); supportedImageMimeTypes.add('image/jxl');
}); });
img.src = 'data:image/jxl;base64,/woIAAAMABKIAgC4AF3lEgA='; // Small valid JPEG XL image jxlImg.src = 'data:image/jxl;base64,/woIAAAMABKIAgC4AF3lEgA='; // Small valid JPEG XL image
const heicImg = new Image();
heicImg.addEventListener('load', () => {
supportedImageMimeTypes.add('image/heic');
});
heicImg.src =
'data:image/heic;base64,AAAAGGZ0eXBoZWljAAAAAG1pZjFoZWljAAABrW1ldGEAAAAAAAAAIWhkbHIAAAAAAAAAAHBpY3QAAAAAAAAAAAAAAAAAAAAADnBpdG0AAAAAAAIAAAAQaWRhdAAAAAAAAQABAAAAOGlsb2MBAAAAREAAAgABAAAAAAAAAc0AAQAAAAAAAAAsAAIAAQAAAAAAAAABAAAAAAAAAAgAAAA4aWluZgAAAAAAAgAAABVpbmZlAgAAAQABAABodmMxAAAAABVpbmZlAgAAAAACAABncmlkAAAAANhpcHJwAAAAtmlwY28AAAB2aHZjQwEDcAAAAAAAAAAAAB7wAPz9+PgAAA8DIAABABhAAQwB//8DcAAAAwCQAAADAAADAB66AkAhAAEAKkIBAQNwAAADAJAAAAMAAAMAHqAggQWW6q6a5uBAQMCAAAADAIAAAAMAhCIAAQAGRAHBc8GJAAAAFGlzcGUAAAAAAAAAAQAAAAEAAAAUaXNwZQAAAAAAAABAAAAAQAAAABBwaXhpAAAAAAMICAgAAAAaaXBtYQAAAAAAAAACAAECgQMAAgIChAAAABppcmVmAAAAAAAAAA5kaW1nAAIAAQABAAAANG1kYXQAAAAoKAGvCchMZYA50NoPIfzz81Qfsm577GJt3lf8kLAr+NbNIoeRR7JeYA=='; // Small valid HEIC/HEIF image
} }
checkJxlSupport(); void addSupportedMimeTypes();
/** /**
* Returns true if the asset is an image supported by web browsers, false otherwise * Returns true if the asset is an image supported by web browsers, false otherwise