修复内存溢出问题

This commit is contained in:
2025-09-19 01:25:30 +08:00
parent 803cc100be
commit 9674740c0d
13 changed files with 1085 additions and 337 deletions

View File

@@ -4,7 +4,7 @@ import { Button } from './ui/Button';
import { useAppStore } from '../store/useAppStore';
import { useImageGeneration, useImageEditing } from '../hooks/useImageGeneration';
import { Upload, Wand2, Edit3, MousePointer, HelpCircle, ChevronDown, ChevronRight, RotateCcw } from 'lucide-react';
import { blobToBase64 } from '../utils/imageUtils';
import { blobToBase64, urlToBlob } from '../utils/imageUtils';
import { PromptHints } from './PromptHints';
import { cn } from '../utils/cn';
@@ -32,6 +32,7 @@ export const PromptComposer: React.FC = () => {
showPromptPanel,
setShowPromptPanel,
clearBrushStrokes,
addBlob
} = useAppStore();
const { generate, cancelGeneration } = useImageGeneration();
@@ -42,17 +43,45 @@ export const PromptComposer: React.FC = () => {
const [isDragOver, setIsDragOver] = useState(false);
const fileInputRef = useRef<HTMLInputElement>(null);
const handleGenerate = () => {
const handleGenerate = async () => {
if (!currentPrompt.trim()) return;
if (selectedTool === 'generate') {
const referenceImages = uploadedImages
.filter(img => img.includes('base64,'))
.map(img => img.split('base64,')[1]);
// 将上传的图像转换为Blob对象
const referenceImageBlobs: Blob[] = [];
for (const img of uploadedImages) {
if (img.startsWith('data:')) {
// 从base64数据创建Blob
const base64 = img.split('base64,')[1];
const byteString = atob(base64);
const mimeString = img.split(',')[0].split(':')[1].split(';')[0];
const ab = new ArrayBuffer(byteString.length);
const ia = new Uint8Array(ab);
for (let i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
referenceImageBlobs.push(new Blob([ab], { type: mimeString }));
} else if (img.startsWith('blob:')) {
// 从Blob URL获取Blob
const { getBlob } = useAppStore.getState();
const blob = getBlob(img);
if (blob) {
referenceImageBlobs.push(blob);
}
} else {
// 从URL获取Blob
try {
const blob = await urlToBlob(img);
referenceImageBlobs.push(blob);
} catch (error) {
console.warn('无法获取参考图像:', img, error);
}
}
}
generate({
prompt: currentPrompt,
referenceImages: referenceImages.length > 0 ? referenceImages : undefined,
referenceImages: referenceImageBlobs.length > 0 ? referenceImageBlobs : undefined,
temperature,
seed: seed !== null ? seed : undefined
});
@@ -64,28 +93,28 @@ export const PromptComposer: React.FC = () => {
const handleFileUpload = async (file: File) => {
if (file && file.type.startsWith('image/')) {
try {
const base64 = await blobToBase64(file);
const dataUrl = `data:${file.type};base64,${base64}`;
// 直接使用Blob创建URL
const blobUrl = addBlob(file);
if (selectedTool === 'generate') {
// 添加到参考图像最多2张
if (uploadedImages.length < 2) {
addUploadedImage(dataUrl);
addUploadedImage(blobUrl);
}
} else if (selectedTool === 'edit') {
// 编辑模式下添加到单独的编辑参考图像最多2张
if (editReferenceImages.length < 2) {
addEditReferenceImage(dataUrl);
addEditReferenceImage(blobUrl);
}
// 如果没有画布图像,则设置为画布图像
if (!canvasImage) {
setCanvasImage(dataUrl);
setCanvasImage(blobUrl);
}
} else if (selectedTool === 'mask') {
// 遮罩模式下,立即设置为画布图像
clearUploadedImages();
addUploadedImage(dataUrl);
setCanvasImage(dataUrl);
addUploadedImage(blobUrl);
setCanvasImage(blobUrl);
}
} catch (error) {
console.error('上传图像失败:', error);