mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-11-17 19:24:30 +01:00
optimize
This commit is contained in:
@@ -416,37 +416,37 @@ export const getFileHandle = async (
|
|||||||
/**
|
/**
|
||||||
* attempts to detect if a buffer is a valid image by checking its leading bytes
|
* attempts to detect if a buffer is a valid image by checking its leading bytes
|
||||||
*/
|
*/
|
||||||
const getActualMimeTypeFromImage = (buffer: ArrayBuffer) => {
|
const getActualMimeTypeFromImage = async (file: Blob | File) => {
|
||||||
let mimeType: ValueOf<
|
let mimeType: ValueOf<
|
||||||
Pick<typeof MIME_TYPES, "png" | "jpg" | "gif" | "webp">
|
Pick<typeof MIME_TYPES, "png" | "jpg" | "gif" | "webp">
|
||||||
> | null = null;
|
> | null = null;
|
||||||
|
|
||||||
const leadingBytes = `${[...new Uint8Array(buffer).slice(0, 15)].join(" ")} `;
|
const leadingBytes = [
|
||||||
|
...new Uint8Array(await blobToArrayBuffer(file.slice(0, 15))),
|
||||||
|
].join(" ");
|
||||||
|
|
||||||
// uint8 leading bytes
|
// uint8 leading bytes
|
||||||
const bytes = {
|
const bytes = {
|
||||||
// https://en.wikipedia.org/wiki/Portable_Network_Graphics#File_header
|
// https://en.wikipedia.org/wiki/Portable_Network_Graphics#File_header
|
||||||
png: "137 80 78 71 13 10 26 10 ",
|
png: /^137 80 78 71 13 10 26 10\b/,
|
||||||
// https://en.wikipedia.org/wiki/JPEG#Syntax_and_structure
|
// https://en.wikipedia.org/wiki/JPEG#Syntax_and_structure
|
||||||
// jpg is a bit wonky. Checking the first three bytes should be enough,
|
// jpg is a bit wonky. Checking the first three bytes should be enough,
|
||||||
// but may yield false positives. (https://stackoverflow.com/a/23360709/927631)
|
// but may yield false positives. (https://stackoverflow.com/a/23360709/927631)
|
||||||
jpg: "255 216 255 ",
|
jpg: /^255 216 255\b/,
|
||||||
// https://en.wikipedia.org/wiki/GIF#Example_GIF_file
|
// https://en.wikipedia.org/wiki/GIF#Example_GIF_file
|
||||||
gif: "71 73 70 56 57 97 ",
|
gif: /^71 73 70 56 57 97\b/,
|
||||||
// 4 bytes for RIFF + 4 bytes for chunk size + WEBP identifier
|
// 4 bytes for RIFF + 4 bytes for chunk size + WEBP identifier
|
||||||
webp: /^82 73 70 70 \d+ \d+ \d+ \d+ 87 69 66 80 86 80 56/,
|
webp: /^82 73 70 70 \d+ \d+ \d+ \d+ 87 69 66 80 86 80 56\b/,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (leadingBytes.startsWith(bytes.png)) {
|
for (const type of Object.keys(bytes) as (keyof typeof bytes)[]) {
|
||||||
mimeType = MIME_TYPES.png;
|
if (leadingBytes.match(bytes[type])) {
|
||||||
} else if (leadingBytes.startsWith(bytes.jpg)) {
|
mimeType = MIME_TYPES[type];
|
||||||
mimeType = MIME_TYPES.jpg;
|
break;
|
||||||
} else if (leadingBytes.startsWith(bytes.gif)) {
|
}
|
||||||
mimeType = MIME_TYPES.gif;
|
|
||||||
} else if (bytes.webp.test(leadingBytes)) {
|
|
||||||
mimeType = MIME_TYPES.webp;
|
|
||||||
}
|
}
|
||||||
return mimeType;
|
|
||||||
|
return mimeType || file.type || null;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const createFile = (
|
export const createFile = (
|
||||||
@@ -478,7 +478,7 @@ export const normalizeFile = async (file: File) => {
|
|||||||
// when the file is an image, make sure the extension corresponds to the
|
// when the file is an image, make sure the extension corresponds to the
|
||||||
// actual mimeType (this is an edge case, but happens - especially
|
// actual mimeType (this is an edge case, but happens - especially
|
||||||
// with AI generated images)
|
// with AI generated images)
|
||||||
const mimeType = getActualMimeTypeFromImage(await blobToArrayBuffer(file));
|
const mimeType = await getActualMimeTypeFromImage(file);
|
||||||
if (mimeType && mimeType !== file.type) {
|
if (mimeType && mimeType !== file.type) {
|
||||||
file = createFile(file, mimeType, file.name);
|
file = createFile(file, mimeType, file.name);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user