156 lines
No EOL
5.6 KiB
TypeScript
156 lines
No EOL
5.6 KiB
TypeScript
/**
|
|
* Converts a Uint8Array buffer to a usable image URL
|
|
* @param imageBuffer The Uint8Array containing image data
|
|
* @param mimeType The MIME type of the image (default: 'image/png')
|
|
* @returns A data URL or Blob URL that can be used as an image source
|
|
*/
|
|
export function bufferToImageUrl(imageBuffer: Uint8Array, mimeType: string = 'image/png'): string {
|
|
if(imageBuffer.length == 1) {
|
|
throw new Error("This is the default logo.")
|
|
}
|
|
// Method 1: Create a data URL
|
|
const base64String = arrayBufferToBase64(imageBuffer);
|
|
return `data:${mimeType};base64,${base64String}`;
|
|
|
|
// Alternative Method 2: Create a Blob URL
|
|
// const blob = new Blob([imageBuffer], { type: mimeType });
|
|
// return URL.createObjectURL(blob);
|
|
}
|
|
|
|
/**
|
|
* Helper function to convert ArrayBuffer to base64 string
|
|
* @param buffer The ArrayBuffer to convert
|
|
* @returns Base64 encoded string
|
|
*/
|
|
export function arrayBufferToBase64(buffer: Uint8Array): string {
|
|
let binary = '';
|
|
const bytes = new Uint8Array(buffer);
|
|
const len = bytes.byteLength;
|
|
|
|
for (let i = 0; i < len; i++) {
|
|
binary += String.fromCharCode(bytes[i]);
|
|
}
|
|
|
|
return btoa(binary);
|
|
}
|
|
|
|
export async function convertImageToUint8Array(file: File): Promise<Uint8Array> {
|
|
return new Promise((resolve, reject) => {
|
|
// Create a FileReader to read the file
|
|
const reader = new FileReader();
|
|
|
|
// Set up the onload event handler
|
|
reader.onload = function() {
|
|
// Create an image element to load the file data
|
|
const img = new Image();
|
|
|
|
img.onload = function() {
|
|
// Create a canvas to draw the image
|
|
const canvas = document.createElement('canvas');
|
|
const ctx = canvas.getContext('2d');
|
|
|
|
if (!ctx) {
|
|
reject(new Error('Failed to get canvas context'));
|
|
return;
|
|
}
|
|
|
|
// Set canvas dimensions to match image
|
|
canvas.width = img.width;
|
|
canvas.height = img.height;
|
|
|
|
// Draw the image on the canvas
|
|
ctx.drawImage(img, 0, 0);
|
|
|
|
// Convert the canvas to a JPEG blob
|
|
canvas.toBlob((blob) => {
|
|
if (!blob) {
|
|
reject(new Error('Failed to create blob'));
|
|
return;
|
|
}
|
|
|
|
// Convert blob to ArrayBuffer
|
|
const blobReader = new FileReader();
|
|
blobReader.onload = function() {
|
|
if (!blobReader.result || typeof blobReader.result === 'string') {
|
|
reject(new Error('Failed to read blob data'));
|
|
return;
|
|
}
|
|
|
|
// Convert ArrayBuffer to Uint8Array
|
|
const uint8Array = new Uint8Array(blobReader.result);
|
|
resolve(uint8Array);
|
|
};
|
|
|
|
blobReader.onerror = function() {
|
|
reject(new Error('Failed to read blob'));
|
|
};
|
|
|
|
blobReader.readAsArrayBuffer(blob);
|
|
}, 'image/jpeg', 0.85); // 0.85 is the quality level (0-1)
|
|
};
|
|
|
|
img.onerror = function() {
|
|
reject(new Error('Failed to load image'));
|
|
};
|
|
|
|
// Load the image with the file data
|
|
img.src = reader.result as string;
|
|
};
|
|
|
|
reader.onerror = function() {
|
|
reject(new Error('Failed to read file'));
|
|
};
|
|
|
|
// Read the file as a data URL
|
|
reader.readAsDataURL(file);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Converts a link (data URL or HTTP/HTTPS URL) to a Uint8Array
|
|
* @param link The image link (data URL or HTTP/HTTPS URL)
|
|
* @returns Promise resolving to a Uint8Array containing the image data
|
|
*/
|
|
export async function linkToUint8Array(link: string): Promise<Uint8Array> {
|
|
// Check if the link is a data URL
|
|
if (link.startsWith('data:')) {
|
|
// Extract the base64 part of the data URL
|
|
const matches = link.match(/^data:([^;]+);base64,(.+)$/);
|
|
if (!matches || matches.length !== 3) {
|
|
throw new Error('Invalid data URL format');
|
|
}
|
|
|
|
// Convert base64 to Uint8Array
|
|
const base64Data = matches[2];
|
|
const binaryString = atob(base64Data);
|
|
const length = binaryString.length;
|
|
const bytes = new Uint8Array(length);
|
|
|
|
for (let i = 0; i < length; i++) {
|
|
bytes[i] = binaryString.charCodeAt(i);
|
|
}
|
|
|
|
return bytes;
|
|
}
|
|
// Handle HTTP/HTTPS URLs
|
|
else if (link.startsWith('http://') || link.startsWith('https://')) {
|
|
try {
|
|
// Fetch the image
|
|
const response = await fetch(link);
|
|
|
|
if (!response.ok) {
|
|
throw new Error(`HTTP error! Status: ${response.status}`);
|
|
}
|
|
|
|
// Get the array buffer from the response
|
|
const arrayBuffer = await response.arrayBuffer();
|
|
|
|
// Convert to Uint8Array
|
|
return new Uint8Array(arrayBuffer);
|
|
} catch (error) {
|
|
throw new Error(`Failed to fetch image: ${error instanceof Error ? error.message : String(error)}`);
|
|
}
|
|
} else {
|
|
throw new Error('Unsupported link format. Must be a data URL or HTTP/HTTPS URL');
|
|
}
|
|
} |