import type { ReferenceImage } from "@/types/image"; export function formatBytes(bytes: number) { if (!Number.isFinite(bytes) || bytes <= 0) { return ""; } const units = ["B", "KB", "MB", "GB"]; let value = bytes; let unitIndex = 0; while (value >= 1024 && unitIndex < units.length - 1) { value /= 1024; unitIndex += 1; } return `${value >= 10 || unitIndex === 0 ? value.toFixed(0) : value.toFixed(1)} ${units[unitIndex]}`; } export function formatDuration(ms: number) { const value = Math.max(0, Math.floor(ms / 1000)); const minutes = Math.floor(value / 60); const seconds = value % 60; return minutes ? `${minutes}分${String(seconds).padStart(2, "0")}秒` : `${seconds}秒`; } export function getDataUrlByteSize(dataUrl: string) { const base64 = dataUrl.split(",", 2)[1]; if (!base64) { return 0; } const padding = base64.endsWith("==") ? 2 : base64.endsWith("=") ? 1 : 0; return Math.max(0, Math.floor((base64.length * 3) / 4) - padding); } export function readFileAsDataUrl(file: File) { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = () => resolve(String(reader.result || "")); reader.onerror = () => reject(new Error("读取图片失败")); reader.readAsDataURL(file); }); } export function readImageMeta(dataUrl: string) { return new Promise<{ width: number; height: number; mimeType: string }>((resolve) => { const image = new Image(); const done = () => resolve({ width: image.naturalWidth || 1024, height: image.naturalHeight || 1024, mimeType: dataUrl.match(/^data:([^;]+)/)?.[1] || "image/png" }); image.onload = done; image.onerror = done; setTimeout(done, 3000); image.src = dataUrl; }); } export function dataUrlToFile(image: ReferenceImage) { const [header, content] = image.dataUrl.split(",", 2); const mimeType = header.match(/data:(.*?);base64/)?.[1] || image.type || "image/png"; const binary = atob(content || ""); const bytes = new Uint8Array(binary.length); for (let index = 0; index < binary.length; index += 1) { bytes[index] = binary.charCodeAt(index); } return new File([bytes], image.name || "reference.png", { type: mimeType }); }