diff --git a/components/image-annotator.tsx b/components/image-annotator.tsx index 945befd..bff7830 100644 --- a/components/image-annotator.tsx +++ b/components/image-annotator.tsx @@ -78,8 +78,23 @@ export function ImageAnnotator({ imageUrl, onConfirm, onCancel, initialResizeMod const fileInputRef = useRef(null); - // 处理拖拽上传 - const handleDrop = useCallback((e: React.DragEvent) => { + // 上传图片到服务器获取 URL 的辅助函数 + const uploadImageFile = async (file: File): Promise => { + const formData = new FormData(); + formData.append("file", file); + const response = await fetch("/api/files/upload", { + method: "POST", + body: formData, + }); + if (!response.ok) { + throw new Error("上传失败"); + } + const result = await response.json(); + return result.url; + }; + + // 处理拖拽上传 - 先上传到服务器获取URL + const handleDrop = useCallback(async (e: React.DragEvent) => { e.preventDefault(); e.stopPropagation(); @@ -94,11 +109,13 @@ export function ImageAnnotator({ imageUrl, onConfirm, onCancel, initialResizeMod toast.error("图片大小不能超过 10MB"); return; } - const reader = new FileReader(); - reader.onload = (e) => { - const result = e.target?.result as string; - setOriginalImageUrl(result); + + try { setIsLoading(true); + toast.info("正在上传图片..."); + const imageUrl = await uploadImageFile(file); + + setOriginalImageUrl(imageUrl); setProcessedImageUrl(null); setProcessedImageBase64(null); setProcessType(null); @@ -106,9 +123,22 @@ export function ImageAnnotator({ imageUrl, onConfirm, onCancel, initialResizeMod setCurrentAction(null); const img = new window.Image(); - img.src = result; - }; - reader.readAsDataURL(file); + img.crossOrigin = "anonymous"; + img.onload = () => { + setImage(img); + setIsLoading(false); + }; + img.onerror = () => { + setIsLoading(false); + toast.error("图片加载失败"); + }; + img.src = imageUrl; + toast.success("图片上传成功"); + } catch (error) { + console.error("上传图片失败:", error); + toast.error("上传失败,请重试"); + setIsLoading(false); + } } }, []); @@ -117,11 +147,11 @@ export function ImageAnnotator({ imageUrl, onConfirm, onCancel, initialResizeMod e.stopPropagation(); }, []); - // 处理粘贴上传 + // 处理粘贴上传 - 先上传到服务器获取URL useEffect(() => { if (!mounted || originalImageUrl) return; - const handlePaste = (e: ClipboardEvent) => { + const handlePaste = async (e: ClipboardEvent) => { const items = e.clipboardData?.items; if (!items) return; @@ -135,11 +165,12 @@ export function ImageAnnotator({ imageUrl, onConfirm, onCancel, initialResizeMod return; } - const reader = new FileReader(); - reader.onload = (e) => { - const result = e.target?.result as string; - setOriginalImageUrl(result); + try { setIsLoading(true); + toast.info("正在上传图片..."); + const imageUrl = await uploadImageFile(file); + + setOriginalImageUrl(imageUrl); setProcessedImageUrl(null); setProcessedImageBase64(null); setProcessType(null); @@ -147,9 +178,22 @@ export function ImageAnnotator({ imageUrl, onConfirm, onCancel, initialResizeMod setCurrentAction(null); const img = new window.Image(); - img.src = result; - }; - reader.readAsDataURL(file); + img.crossOrigin = "anonymous"; + img.onload = () => { + setImage(img); + setIsLoading(false); + }; + img.onerror = () => { + setIsLoading(false); + toast.error("图片加载失败"); + }; + img.src = imageUrl; + toast.success("图片上传成功"); + } catch (error) { + console.error("上传图片失败:", error); + toast.error("上传失败,请重试"); + setIsLoading(false); + } break; } } @@ -255,19 +299,22 @@ export function ImageAnnotator({ imageUrl, onConfirm, onCancel, initialResizeMod }); }, []); - // 处理本地图片上传 - const handleImageUpload = (e: React.ChangeEvent) => { + // 处理本地图片上传 - 先上传到服务器获取URL + const handleImageUpload = async (e: React.ChangeEvent) => { const file = e.target.files?.[0]; if (file) { if (file.size > 10 * 1024 * 1024) { toast.error("图片大小不能超过 10MB"); + e.target.value = ""; return; } - const reader = new FileReader(); - reader.onload = (e) => { - const result = e.target?.result as string; - setOriginalImageUrl(result); + + try { setIsLoading(true); + toast.info("正在上传图片..."); + const imageUrl = await uploadImageFile(file); + + setOriginalImageUrl(imageUrl); // 重置状态 setProcessedImageUrl(null); setProcessedImageBase64(null); @@ -282,9 +329,17 @@ export function ImageAnnotator({ imageUrl, onConfirm, onCancel, initialResizeMod setImage(img); setIsLoading(false); }; - img.src = result; - }; - reader.readAsDataURL(file); + img.onerror = () => { + setIsLoading(false); + toast.error("图片加载失败"); + }; + img.src = imageUrl; + toast.success("图片上传成功"); + } catch (error) { + console.error("上传图片失败:", error); + toast.error("上传失败,请重试"); + setIsLoading(false); + } } // 重置 input e.target.value = "";