修复内存溢出问题

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

@@ -6,16 +6,16 @@ const genAI = new GoogleGenAI({ apiKey: API_KEY })
export interface GenerationRequest {
prompt: string
referenceImages?: string[] // base64数组
referenceImages?: Blob[] // Blob数组
temperature?: number
seed?: number
}
export interface EditRequest {
instruction: string
originalImage: string // base64
referenceImages?: string[] // base64数组
maskImage?: string // base64
originalImage: Blob // Blob
referenceImages?: Blob[] // Blob数组
maskImage?: Blob // Blob
temperature?: number
seed?: number
}
@@ -27,18 +27,37 @@ export interface UsageMetadata {
}
export interface SegmentationRequest {
image: string // base64
image: Blob // Blob
query: string // "像素(x,y)处的对象" 或 "红色汽车"
}
export class GeminiService {
async generateImage(request: GenerationRequest): Promise<{ images: string[]; usageMetadata?: any }> {
// 将Blob转换为base64的辅助函数
private async blobToBase64(blob: Blob): Promise<string> {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => {
const result = reader.result as string;
const base64 = result.split(',')[1]; // Remove data:image/png;base64, prefix
resolve(base64);
};
reader.onerror = reject;
reader.readAsDataURL(blob);
});
}
async generateImage(request: GenerationRequest): Promise<{ images: Blob[]; usageMetadata?: any }> {
try {
const contents: any[] = [{ text: request.prompt }]
// 如果提供了参考图像则添加
if (request.referenceImages && request.referenceImages.length > 0) {
request.referenceImages.forEach(image => {
// 将Blob转换为base64以发送到API
const base64Images = await Promise.all(
request.referenceImages.map(blob => this.blobToBase64(blob))
);
base64Images.forEach(image => {
contents.push({
inlineData: {
mimeType: 'image/png',
@@ -82,13 +101,22 @@ export class GeminiService {
}
}
const images: string[] = []
const images: Blob[] = []
// 检查响应是否存在以及是否有内容
if (response.candidates && response.candidates.length > 0 && response.candidates[0].content && response.candidates[0].content.parts) {
for (const part of response.candidates[0].content.parts) {
if (part.inlineData) {
images.push(part.inlineData.data)
// 将返回的base64数据转换为Blob
const byteString = atob(part.inlineData.data);
const mimeString = part.inlineData.mimeType || 'image/png';
const ab = new ArrayBuffer(byteString.length);
const ia = new Uint8Array(ab);
for (let i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
const blob = new Blob([ab], { type: mimeString });
images.push(blob);
}
}
}
@@ -106,21 +134,29 @@ export class GeminiService {
}
}
async editImage(request: EditRequest): Promise<{ images: string[]; usageMetadata?: any }> {
async editImage(request: EditRequest): Promise<{ images: Blob[]; usageMetadata?: any }> {
try {
// 将Blob转换为base64以发送到API
const originalImageBase64 = await this.blobToBase64(request.originalImage);
const contents = [
{ text: this.buildEditPrompt(request) },
{
inlineData: {
mimeType: 'image/png',
data: request.originalImage,
data: originalImageBase64,
},
},
]
// 如果提供了参考图像则添加
if (request.referenceImages && request.referenceImages.length > 0) {
request.referenceImages.forEach(image => {
// 将Blob转换为base64以发送到API
const base64ReferenceImages = await Promise.all(
request.referenceImages.map(blob => this.blobToBase64(blob))
);
base64ReferenceImages.forEach(image => {
contents.push({
inlineData: {
mimeType: 'image/png',
@@ -131,10 +167,12 @@ export class GeminiService {
}
if (request.maskImage) {
// 将Blob转换为base64以发送到API
const maskImageBase64 = await this.blobToBase64(request.maskImage);
contents.push({
inlineData: {
mimeType: 'image/png',
data: request.maskImage,
data: maskImageBase64,
},
})
}
@@ -170,13 +208,22 @@ export class GeminiService {
}
}
const images: string[] = []
const images: Blob[] = []
// 检查响应是否存在以及是否有内容
if (response.candidates && response.candidates.length > 0 && response.candidates[0].content && response.candidates[0].content.parts) {
for (const part of response.candidates[0].content.parts) {
if (part.inlineData) {
images.push(part.inlineData.data)
// 将返回的base64数据转换为Blob
const byteString = atob(part.inlineData.data);
const mimeString = part.inlineData.mimeType || 'image/png';
const ab = new ArrayBuffer(byteString.length);
const ia = new Uint8Array(ab);
for (let i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
const blob = new Blob([ab], { type: mimeString });
images.push(blob);
}
}
}
@@ -196,6 +243,9 @@ export class GeminiService {
async segmentImage(request: SegmentationRequest): Promise<any> {
try {
// 将Blob转换为base64以发送到API
const imageBase64 = await this.blobToBase64(request.image);
const prompt = [
{
text: `分析此图像并为以下对象创建分割遮罩: ${request.query}
@@ -216,7 +266,7 @@ export class GeminiService {
{
inlineData: {
mimeType: 'image/png',
data: request.image,
data: imageBase64,
},
},
]