|
@@ -0,0 +1,75 @@
|
|
|
|
|
+export function fileToBase64(file: File): Promise<string> {
|
|
|
|
|
+ return blobToBase64(file);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+export function blobToBase64(blob: Blob, fast = true): Promise<string> {
|
|
|
|
|
+ return fast
|
|
|
|
|
+ ? blob
|
|
|
|
|
+ .arrayBuffer()
|
|
|
|
|
+ .then((buffer) => new Uint8Array(buffer))
|
|
|
|
|
+ .then((bytes) => {
|
|
|
|
|
+ let binary = '';
|
|
|
|
|
+ for (const byte of bytes) binary += String.fromCharCode(byte);
|
|
|
|
|
+ return `data:${blob.type};base64,${btoa(binary)}`;
|
|
|
|
|
+ })
|
|
|
|
|
+ : new Promise((resolve, reject) => {
|
|
|
|
|
+ const reader = new FileReader();
|
|
|
|
|
+ reader.onload = () => resolve(reader.result as string);
|
|
|
|
|
+ reader.onerror = reject;
|
|
|
|
|
+ reader.readAsDataURL(blob);
|
|
|
|
|
+ });
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+export function blobToFile(blob: Blob, filename?: string): File {
|
|
|
|
|
+ return new File([blob], filename ?? 'file', { type: blob.type });
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+export function base64ToBlob(base64: string): Blob {
|
|
|
|
|
+ const [header, data] = base64.split(',');
|
|
|
|
|
+
|
|
|
|
|
+ const mimeMatch = header.match(/:(.*?);/);
|
|
|
|
|
+ const mime = mimeMatch ? mimeMatch[1] : '';
|
|
|
|
|
+
|
|
|
|
|
+ const binary = atob(data);
|
|
|
|
|
+ const len = binary.length;
|
|
|
|
|
+ const buffer = new Uint8Array(len);
|
|
|
|
|
+
|
|
|
|
|
+ for (let i = 0; i < len; i++) buffer[i] = binary.charCodeAt(i);
|
|
|
|
|
+
|
|
|
|
|
+ return new Blob([buffer], { type: mime });
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+export function base64ToFile(base64: string, filename?: string): File {
|
|
|
|
|
+ const blob = base64ToBlob(base64);
|
|
|
|
|
+ return blobToFile(blob, filename);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+export type TargetType = 'file' | 'blob' | 'base64';
|
|
|
|
|
+
|
|
|
|
|
+type ConvertResult<T extends TargetType> = T extends 'file' ? File : T extends 'blob' ? Blob : T extends 'base64' ? string : never;
|
|
|
|
|
+
|
|
|
|
|
+async function convert<T extends TargetType>(input: File | Blob | string, type: T, options?: { fast?: boolean; filename?: string }): Promise<ConvertResult<T>> {
|
|
|
|
|
+ switch (type) {
|
|
|
|
|
+ case 'blob': {
|
|
|
|
|
+ if (typeof input === 'string') input = base64ToBlob(input);
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ case 'file': {
|
|
|
|
|
+ if (input instanceof File) break;
|
|
|
|
|
+ if (typeof input === 'string') input = base64ToFile(input, options?.filename);
|
|
|
|
|
+ else input = blobToFile(input, options?.filename);
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ case 'base64': {
|
|
|
|
|
+ if (typeof input === 'string') break;
|
|
|
|
|
+ if (input instanceof File) input = await fileToBase64(input);
|
|
|
|
|
+ else if (input instanceof Blob) input = await blobToBase64(input, options?.fast);
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ default:
|
|
|
|
|
+ throw new Error('Unsupported type');
|
|
|
|
|
+ }
|
|
|
|
|
+ return input as ConvertResult<T>;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+export default convert;
|