diff --git a/script.js b/script.js index e1f8adc..2b44a35 100644 --- a/script.js +++ b/script.js @@ -50,6 +50,45 @@ const ERROR_MESSAGES = { // 工具函数 const utils = { + // 将base64转换为Blob URL + base64ToBlobUrl: function(base64Data) { + try { + // 检查是否已经是Blob URL + if (base64Data.startsWith('blob:')) { + return base64Data; + } + + // 提取base64数据的MIME类型和纯数据部分 + const parts = base64Data.split(';base64,'); + if (parts.length !== 2) { + console.warn('Invalid base64 format, returning original data'); + return base64Data; + } + + const contentType = parts[0].split(':')[1]; + const byteCharacters = atob(parts[1]); + + // 转换为ArrayBuffer + const byteNumbers = new Array(byteCharacters.length); + for (let i = 0; i < byteCharacters.length; i++) { + byteNumbers[i] = byteCharacters.charCodeAt(i); + } + const byteArray = new Uint8Array(byteNumbers); + + // 创建Blob和URL + const blob = new Blob([byteArray], { type: contentType }); + const blobUrl = URL.createObjectURL(blob); + + // 存储原始base64数据以便后续使用(如下载) + blobUrl._originalBase64 = base64Data; + + return blobUrl; + } catch (error) { + console.error('Error converting base64 to Blob URL:', error); + return base64Data; // 出错时返回原始数据 + } + }, + // 格式化文件大小 formatFileSize: function(bytes) { if (bytes === 0) return '0 Bytes'; @@ -669,10 +708,11 @@ const apiService = { const messageContent = choice.message.content; const images = []; - // 提取图像数据 + // 提取图像数据并转换为Blob URL if (choice.message.images) { choice.message.images.forEach(img => { - images.push(img.image_url.url); + const blobUrl = utils.base64ToBlobUrl(img.image_url.url); + images.push(blobUrl); }); } @@ -773,8 +813,12 @@ const uiController = { imageDiv.className = 'image-item fade-in'; const imageId = Date.now() + Math.random(); + + // 确保imageUrl是Blob URL + const displayUrl = imageUrl.startsWith('blob:') ? imageUrl : utils.base64ToBlobUrl(imageUrl); + imageDiv.innerHTML = ` - Generated Image + Generated Image
@@ -884,8 +928,11 @@ const uiController = { placeholder.className = 'image-item fade-in'; placeholder.id = ''; + // 确保imageUrl是Blob URL + const displayUrl = imageUrl.startsWith('blob:') ? imageUrl : utils.base64ToBlobUrl(imageUrl); + placeholder.innerHTML = ` - Generated Image + Generated Image
@@ -1319,9 +1366,13 @@ const uiController = { // 显示图像预览 displayImagePreview: function(imageData) { const preview = document.getElementById('imagePreview'); + + // 确保图像数据是Blob URL + const displayUrl = imageData.data.startsWith('blob:') ? imageData.data : utils.base64ToBlobUrl(imageData.data); + preview.innerHTML = `
- ${imageData.name} + ${imageData.name}
${utils.formatFileSize(imageData.size)} @@ -1942,10 +1993,37 @@ const app = { // 下载图像 downloadImage: function(imageUrl) { - const link = document.createElement('a'); - link.href = imageUrl; - link.download = `generated-image-${Date.now()}.png`; - link.click(); + // 检查是否是Blob URL并且有原始base64数据 + if (imageUrl.startsWith('blob:') && imageUrl._originalBase64) { + // 使用原始base64数据下载 + const link = document.createElement('a'); + link.href = imageUrl._originalBase64; + link.download = `generated-image-${Date.now()}.png`; + link.click(); + } else if (imageUrl.startsWith('blob:')) { + // 如果没有原始base64数据,通过fetch获取Blob数据 + fetch(imageUrl) + .then(response => response.blob()) + .then(blob => { + const url = URL.createObjectURL(blob); + const link = document.createElement('a'); + link.href = url; + link.download = `generated-image-${Date.now()}.png`; + link.click(); + // 清理临时URL + setTimeout(() => URL.revokeObjectURL(url), 100); + }) + .catch(error => { + console.error('Error downloading image:', error); + utils.showNotification('下载图像失败', 'danger'); + }); + } else { + // 如果是普通URL,直接下载 + const link = document.createElement('a'); + link.href = imageUrl; + link.download = `generated-image-${Date.now()}.png`; + link.click(); + } }, // 全部下载图像