|
1 | | -import heic2any from "heic2any"; |
| 1 | +import { CACHE_URL_PREFIX, UPLOAD_URL } from "@/app/constant"; |
| 2 | +import { RequestMessage } from "@/app/client/api"; |
2 | 3 |
|
3 | | -export function compressImage(file: File, maxSize: number): Promise<string> { |
| 4 | +export function compressImage(file: Blob, maxSize: number): Promise<string> { |
4 | 5 | return new Promise((resolve, reject) => { |
5 | 6 | const reader = new FileReader(); |
6 | 7 | reader.onload = (readerEvent: any) => { |
@@ -40,15 +41,104 @@ export function compressImage(file: File, maxSize: number): Promise<string> { |
40 | 41 | reader.onerror = reject; |
41 | 42 |
|
42 | 43 | if (file.type.includes("heic")) { |
43 | | - heic2any({ blob: file, toType: "image/jpeg" }) |
44 | | - .then((blob) => { |
45 | | - reader.readAsDataURL(blob as Blob); |
46 | | - }) |
47 | | - .catch((e) => { |
48 | | - reject(e); |
49 | | - }); |
| 44 | + try { |
| 45 | + const heic2any = require("heic2any"); |
| 46 | + heic2any({ blob: file, toType: "image/jpeg" }) |
| 47 | + .then((blob: Blob) => { |
| 48 | + reader.readAsDataURL(blob); |
| 49 | + }) |
| 50 | + .catch((e: any) => { |
| 51 | + reject(e); |
| 52 | + }); |
| 53 | + } catch (e) { |
| 54 | + reject(e); |
| 55 | + } |
50 | 56 | } |
51 | 57 |
|
52 | 58 | reader.readAsDataURL(file); |
53 | 59 | }); |
54 | 60 | } |
| 61 | + |
| 62 | +export async function preProcessImageContent( |
| 63 | + content: RequestMessage["content"], |
| 64 | +) { |
| 65 | + if (typeof content === "string") { |
| 66 | + return content; |
| 67 | + } |
| 68 | + const result = []; |
| 69 | + for (const part of content) { |
| 70 | + if (part?.type == "image_url" && part?.image_url?.url) { |
| 71 | + try { |
| 72 | + const url = await cacheImageToBase64Image(part?.image_url?.url); |
| 73 | + result.push({ type: part.type, image_url: { url } }); |
| 74 | + } catch (error) { |
| 75 | + console.error("Error processing image URL:", error); |
| 76 | + } |
| 77 | + } else { |
| 78 | + result.push({ ...part }); |
| 79 | + } |
| 80 | + } |
| 81 | + return result; |
| 82 | +} |
| 83 | + |
| 84 | +const imageCaches: Record<string, string> = {}; |
| 85 | +export function cacheImageToBase64Image(imageUrl: string) { |
| 86 | + if (imageUrl.includes(CACHE_URL_PREFIX)) { |
| 87 | + if (!imageCaches[imageUrl]) { |
| 88 | + const reader = new FileReader(); |
| 89 | + return fetch(imageUrl, { |
| 90 | + method: "GET", |
| 91 | + mode: "cors", |
| 92 | + credentials: "include", |
| 93 | + }) |
| 94 | + .then((res) => res.blob()) |
| 95 | + .then( |
| 96 | + async (blob) => |
| 97 | + (imageCaches[imageUrl] = await compressImage(blob, 256 * 1024)), |
| 98 | + ); // compressImage |
| 99 | + } |
| 100 | + return Promise.resolve(imageCaches[imageUrl]); |
| 101 | + } |
| 102 | + return Promise.resolve(imageUrl); |
| 103 | +} |
| 104 | + |
| 105 | +export function base64Image2Blob(base64Data: string, contentType: string) { |
| 106 | + const byteCharacters = atob(base64Data); |
| 107 | + const byteNumbers = new Array(byteCharacters.length); |
| 108 | + for (let i = 0; i < byteCharacters.length; i++) { |
| 109 | + byteNumbers[i] = byteCharacters.charCodeAt(i); |
| 110 | + } |
| 111 | + const byteArray = new Uint8Array(byteNumbers); |
| 112 | + return new Blob([byteArray], { type: contentType }); |
| 113 | +} |
| 114 | + |
| 115 | +export function uploadImage(file: File): Promise<string> { |
| 116 | + if (!window._SW_ENABLED) { |
| 117 | + // if serviceWorker register error, using compressImage |
| 118 | + return compressImage(file, 256 * 1024); |
| 119 | + } |
| 120 | + const body = new FormData(); |
| 121 | + body.append("file", file); |
| 122 | + return fetch(UPLOAD_URL, { |
| 123 | + method: "post", |
| 124 | + body, |
| 125 | + mode: "cors", |
| 126 | + credentials: "include", |
| 127 | + }) |
| 128 | + .then((res) => res.json()) |
| 129 | + .then((res) => { |
| 130 | + console.log("res", res); |
| 131 | + if (res?.code == 0 && res?.data) { |
| 132 | + return res?.data; |
| 133 | + } |
| 134 | + throw Error(`upload Error: ${res?.msg}`); |
| 135 | + }); |
| 136 | +} |
| 137 | + |
| 138 | +export function removeImage(imageUrl: string) { |
| 139 | + return fetch(imageUrl, { |
| 140 | + method: "DELETE", |
| 141 | + mode: "cors", |
| 142 | + credentials: "include", |
| 143 | + }); |
| 144 | +} |
0 commit comments