mirror of
https://github.com/enricoros/big-AGI.git
synced 2026-05-10 21:50:14 -07:00
Fix mimetype change on conversions
This commit is contained in:
@@ -1,10 +1,49 @@
|
||||
/**
|
||||
* Converts a canvas to a data URL and extracts the MIME type and Base64 data
|
||||
* @param canvas The canvas element to convert
|
||||
* @param requestedMimeType The desired MIME type for the image
|
||||
* @param imageQuality A number between 0 and 1 indicating image quality for lossy formats
|
||||
* @param userLogLabel A label to use in console warnings
|
||||
*/
|
||||
export function canvasToDataURLAndMimeType(
|
||||
canvas: HTMLCanvasElement,
|
||||
requestedMimeType: string,
|
||||
imageQuality: number | undefined,
|
||||
userLogLabel: string,
|
||||
): { mimeType: string; base64Data: string } {
|
||||
|
||||
// Extract the actual MIME type and Base64 data efficiently
|
||||
const dataUrl = canvas.toDataURL(requestedMimeType, imageQuality);
|
||||
|
||||
const colonIndex = dataUrl.indexOf(':');
|
||||
const semicolonIndex = dataUrl.indexOf(';', colonIndex);
|
||||
if (colonIndex === -1 || semicolonIndex === -1)
|
||||
throw new Error('canvasToDataURLAndMimeType: Invalid data URL format.');
|
||||
const actualMimeType = dataUrl.slice(colonIndex + 1, semicolonIndex);
|
||||
|
||||
const commaIndex = dataUrl.indexOf(',');
|
||||
if (commaIndex === -1)
|
||||
throw new Error('canvasToDataURLAndMimeType: Invalid data URL comma.');
|
||||
const base64Data = dataUrl.slice(commaIndex + 1);
|
||||
|
||||
// Warn if the actual MIME type differs from the requested one
|
||||
if (actualMimeType !== requestedMimeType)
|
||||
console.warn(`${userLogLabel}: requested MIME type "${requestedMimeType}" was not used. Actual MIME type is "${actualMimeType}".`);
|
||||
|
||||
return { mimeType: actualMimeType, base64Data };
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Blob object representing the image contained in the canvas
|
||||
* @param canvas The canvas element to convert to a Blob.
|
||||
* @param imageFormat Browsers are required to support image/png; many will support additional formats including image/jpeg and image/webp.
|
||||
* @param imageQuality A Number between 0 and 1 indicating image quality if the requested type is image/jpeg or image/webp.
|
||||
*/
|
||||
export async function asyncCanvasToBlob(canvas: HTMLCanvasElement, imageFormat: 'image/png' | 'image/jpeg', imageQuality?: number): Promise<Blob | null> {
|
||||
export async function asyncCanvasToBlob(
|
||||
canvas: HTMLCanvasElement,
|
||||
imageFormat: 'image/png' | 'image/jpeg',
|
||||
imageQuality?: number
|
||||
): Promise<Blob | null> {
|
||||
return new Promise((resolve) => canvas.toBlob(resolve, imageFormat, imageQuality));
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
* Also see videoUtils.ts for more image-related functions.
|
||||
*/
|
||||
|
||||
import { canvasToDataURLAndMimeType } from './canvasUtils';
|
||||
import { createBlobURLFromDataURL } from './urlUtils';
|
||||
|
||||
|
||||
@@ -67,11 +68,18 @@ export async function convertBase64Image(base64DataUrl: string, destMimeType: st
|
||||
return;
|
||||
}
|
||||
ctx.drawImage(image, 0, 0);
|
||||
const dataUrl = canvas.toDataURL(destMimeType, destQuality);
|
||||
resolve({
|
||||
mimeType: destMimeType,
|
||||
base64: dataUrl.split(',')[1],
|
||||
});
|
||||
|
||||
// Convert canvas image to a DataURL string
|
||||
try {
|
||||
const { mimeType: actualMimeType, base64Data } = canvasToDataURLAndMimeType(canvas, destMimeType, destQuality, 'image-convert');
|
||||
resolve({
|
||||
mimeType: actualMimeType,
|
||||
base64: base64Data,
|
||||
});
|
||||
} catch (error) {
|
||||
console.warn(`imageUtils: failed to convert image to ${destMimeType}.`, { error });
|
||||
reject(new Error(`Failed to convert image to '${destMimeType}'.`));
|
||||
}
|
||||
};
|
||||
image.onerror = (error) => {
|
||||
console.warn('Failed to load image for conversion.', error);
|
||||
@@ -222,11 +230,18 @@ export async function resizeBase64ImageIfNeeded(inputMimeType: string, inputBase
|
||||
canvas.width = newWidth;
|
||||
canvas.height = newHeight;
|
||||
ctx.drawImage(image, 0, 0, newWidth, newHeight);
|
||||
const resizedDataUrl = canvas.toDataURL(destMimeType, destQuality);
|
||||
resolve({
|
||||
mimeType: destMimeType,
|
||||
base64: resizedDataUrl.split(',')[1], // Return base64 part only
|
||||
});
|
||||
|
||||
// Convert canvas image to a DataURL string
|
||||
try {
|
||||
const { mimeType: actualMimeType, base64Data } = canvasToDataURLAndMimeType(canvas, destMimeType, destQuality, 'image-resize');
|
||||
resolve({
|
||||
mimeType: actualMimeType,
|
||||
base64: base64Data,
|
||||
});
|
||||
} catch (error) {
|
||||
console.warn(`imageUtils: failed to resize image to '${resizeMode}' as ${destMimeType}.`, { error });
|
||||
reject(new Error(`Failed to resize image to '${resizeMode}' as '${destMimeType}'.`));
|
||||
}
|
||||
};
|
||||
|
||||
image.onerror = (error) => {
|
||||
|
||||
+17
-12
@@ -1,3 +1,5 @@
|
||||
import { canvasToDataURLAndMimeType } from './canvasUtils';
|
||||
|
||||
// configuration
|
||||
const SKIP_LOADING_IN_DEV = false;
|
||||
|
||||
@@ -97,26 +99,29 @@ export async function pdfToImageDataURLs(pdfBuffer: ArrayBuffer, imageMimeType:
|
||||
|
||||
const viewport = page.getViewport({ scale });
|
||||
const canvas = document.createElement('canvas');
|
||||
const context = canvas.getContext('2d');
|
||||
const context = canvas.getContext('2d')!;
|
||||
canvas.height = viewport.height;
|
||||
canvas.width = viewport.width;
|
||||
onProgress((i * 3 + 1) / (pdf.numPages * 3));
|
||||
|
||||
await page.render({
|
||||
canvasContext: context!,
|
||||
canvasContext: context,
|
||||
viewport,
|
||||
}).promise;
|
||||
|
||||
const base64DataUrl = canvas.toDataURL(imageMimeType, imageQuality);
|
||||
const base64Data = base64DataUrl.slice(`data:${imageMimeType};base64,`.length);
|
||||
|
||||
images.push({
|
||||
mimeType: imageMimeType,
|
||||
base64Data,
|
||||
scale,
|
||||
width: viewport.width,
|
||||
height: viewport.height,
|
||||
});
|
||||
// Convert canvas image to a DataURL string
|
||||
try {
|
||||
const { mimeType: actualMimeType, base64Data } = canvasToDataURLAndMimeType(canvas, imageMimeType, imageQuality, 'pdf-to-image');
|
||||
images.push({
|
||||
mimeType: actualMimeType,
|
||||
base64Data,
|
||||
scale,
|
||||
width: viewport.width,
|
||||
height: viewport.height,
|
||||
});
|
||||
} catch (error) {
|
||||
console.warn(`pdfToImageDataURLs: failed to convert image to ${imageMimeType}.`, { error });
|
||||
}
|
||||
onProgress((i * 3 + 2) / (pdf.numPages * 3));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user