利用闲置的any token 畅快使用gpt-image-2生图
- 内容介绍
- 文章标签
- 相关推荐
能直接用的地址,只用填上你的key即可。
AI 图片生成器
效果图
image2348×1878 410 KB
下面是教程以及源码
在你的claude code 中安装如下的mcp
“mcpServers”: {
“edgeone-pages-mcp-server”: {
“url”: “https://mcp-on-edge.edgeone.app/mcp-server”
}
}
ps:使用cc desktop的需要重启desktop,才能使用部署好的edgeone mcp。
接下来就是你按照如下代码生成h5网页并使用mcp发布到edgeone,服务端会给你返回一个地址。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AI 图片生成器</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background: linear-gradient(135deg, #0f0c29, #302b63, #24243e);
min-height: 100vh;
color: #e0e0e0;
}
.container {
max-width: 760px;
margin: 0 auto;
padding: 40px 20px;
}
h1 {
text-align: center;
font-size: 2em;
margin-bottom: 8px;
background: linear-gradient(90deg, #667eea, #764ba2, #f093fb);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.subtitle {
text-align: center;
color: #888;
margin-bottom: 36px;
font-size: 0.95em;
}
.card {
background: rgba(255,255,255,0.05);
border: 1px solid rgba(255,255,255,0.1);
border-radius: 16px;
padding: 28px;
margin-bottom: 24px;
backdrop-filter: blur(10px);
}
label {
display: block;
font-size: 0.85em;
color: #aaa;
margin-bottom: 6px;
font-weight: 500;
}
input, textarea, select {
width: 100%;
padding: 12px 14px;
border: 1px solid rgba(255,255,255,0.15);
border-radius: 10px;
background: rgba(0,0,0,0.3);
color: #f0f0f0;
font-size: 0.95em;
margin-bottom: 18px;
transition: border-color 0.2s;
font-family: inherit;
}
input:focus, textarea:focus {
outline: none;
border-color: #667eea;
}
textarea {
resize: vertical;
min-height: 80px;
}
.row {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 16px;
}
.btn-generate {
width: 100%;
padding: 14px;
border: none;
border-radius: 12px;
font-size: 1.05em;
font-weight: 600;
cursor: pointer;
background: linear-gradient(135deg, #667eea, #764ba2);
color: white;
transition: transform 0.15s, box-shadow 0.2s, opacity 0.2s;
margin-top: 4px;
}
.btn-generate:hover { transform: translateY(-1px); box-shadow: 0 6px 24px rgba(102,126,234,0.4); }
.btn-generate:active { transform: translateY(0); }
.btn-generate:disabled { opacity: 0.6; cursor: not-allowed; transform: none; box-shadow: none; }
.result-area {
text-align: center;
min-height: 120px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.result-area img {
max-width: 100%;
max-height: 520px;
border-radius: 12px;
box-shadow: 0 8px 32px rgba(0,0,0,0.4);
cursor: pointer;
transition: transform 0.2s;
}
.result-area img:hover { transform: scale(1.01); }
.result-actions {
display: flex;
gap: 10px;
margin-top: 16px;
flex-wrap: wrap;
justify-content: center;
}
.btn-action {
padding: 10px 28px;
border: 1px solid rgba(255,255,255,0.2);
border-radius: 10px;
background: rgba(255,255,255,0.08);
color: #e0e0e0;
cursor: pointer;
font-size: 0.9em;
transition: background 0.2s;
}
.btn-action:hover { background: rgba(255,255,255,0.15); }
.spinner {
width: 48px; height: 48px;
border: 4px solid rgba(255,255,255,0.1);
border-top-color: #667eea;
border-radius: 50%;
animation: spin 0.8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
.loading-text {
margin-top: 16px;
color: #aaa;
font-size: 0.9em;
}
.placeholder-icon {
font-size: 3em;
margin-bottom: 12px;
opacity: 0.3;
}
.placeholder-text {
color: #555;
font-size: 0.9em;
}
.error-msg {
color: #ff6b6b;
background: rgba(255,107,107,0.1);
border: 1px solid rgba(255,107,107,0.2);
border-radius: 10px;
padding: 14px;
margin-top: 12px;
font-size: 0.9em;
text-align: left;
word-break: break-all;
}
.size-selector {
display: flex;
gap: 8px;
margin-bottom: 18px;
flex-wrap: wrap;
}
.size-option {
padding: 8px 16px;
border: 1px solid rgba(255,255,255,0.15);
border-radius: 8px;
background: rgba(0,0,0,0.2);
color: #ccc;
cursor: pointer;
font-size: 0.85em;
transition: all 0.2s;
}
.size-option:hover { border-color: #667eea; color: #fff; }
.size-option.active { border-color: #667eea; background: rgba(102,126,234,0.2); color: #fff; }
/* 历史记录区域 */
.history-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 16px;
}
.history-header h2 {
font-size: 1.1em;
color: #aaa;
}
.history-count {
font-size: 0.8em;
color: #666;
background: rgba(255,255,255,0.05);
padding: 4px 12px;
border-radius: 20px;
}
.btn-clear {
padding: 6px 16px;
border: 1px solid rgba(255,100,100,0.3);
border-radius: 8px;
background: rgba(255,100,100,0.08);
color: #ff8888;
cursor: pointer;
font-size: 0.8em;
transition: all 0.2s;
}
.btn-clear:hover { background: rgba(255,100,100,0.15); border-color: rgba(255,100,100,0.5); }
.history-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
gap: 12px;
}
.history-item {
position: relative;
border-radius: 12px;
overflow: hidden;
cursor: pointer;
border: 2px solid transparent;
transition: all 0.2s;
aspect-ratio: 1;
background: rgba(0,0,0,0.3);
}
.history-item:hover {
border-color: #667eea;
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(0,0,0,0.4);
}
.history-item.active {
border-color: #f093fb;
box-shadow: 0 0 0 2px rgba(240,147,251,0.3);
}
.history-item img {
width: 100%;
height: 100%;
object-fit: cover;
}
.history-item .item-meta {
position: absolute;
bottom: 0;
left: 0;
right: 0;
padding: 6px 8px;
background: linear-gradient(transparent, rgba(0,0,0,0.8));
font-size: 0.7em;
color: #ccc;
display: flex;
justify-content: space-between;
align-items: center;
}
.history-item .item-index {
position: absolute;
top: 6px;
left: 6px;
background: rgba(0,0,0,0.6);
color: #aaa;
font-size: 0.7em;
padding: 2px 8px;
border-radius: 10px;
}
.history-item .btn-del {
background: none;
border: none;
color: #ff6b6b;
cursor: pointer;
font-size: 1em;
padding: 0 4px;
opacity: 0;
transition: opacity 0.2s;
}
.history-item:hover .btn-del { opacity: 1; }
.history-empty {
text-align: center;
padding: 40px 20px;
color: #555;
}
/* 全屏预览 */
.lightbox {
display: none;
position: fixed;
inset: 0;
background: rgba(0,0,0,0.92);
z-index: 1000;
justify-content: center;
align-items: center;
cursor: zoom-out;
}
.lightbox.show { display: flex; }
.lightbox img {
max-width: 95vw;
max-height: 92vh;
border-radius: 8px;
box-shadow: 0 12px 48px rgba(0,0,0,0.6);
}
.lightbox-close {
position: fixed;
top: 20px;
right: 24px;
background: rgba(255,255,255,0.1);
border: 1px solid rgba(255,255,255,0.2);
color: white;
width: 40px;
height: 40px;
border-radius: 50%;
font-size: 1.2em;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: background 0.2s;
}
.lightbox-close:hover { background: rgba(255,255,255,0.2); }
footer {
text-align: center;
color: #444;
font-size: 0.8em;
margin-top: 40px;
}
footer a { color: #667eea; text-decoration: none; }
</style>
</head>
<body>
<div class="container">
<h1>🎨 AI 图片生成器</h1>
<p class="subtitle">基于 OpenAI Responses API,在浏览器中直接生成图片</p>
<div class="card">
<div class="row">
<div>
<label>Base URL</label>
<input type="text" id="baseUrl" placeholder="https://api.openai.com/v1" value="https://anyrouter.top/v1">
</div>
<div>
<label>Model</label>
<input type="text" id="model" placeholder="gpt-5.4" value="gpt-5.3-codex">
</div>
</div>
<label>API Key</label>
<input type="password" id="apiKey" placeholder="sk-...(密钥仅在浏览器本地使用,不会上传)">
<label>图片尺寸</label>
<div class="size-selector" id="sizeSelector">
<div class="size-option" data-size="1024x1024">1024×1024</div>
<div class="size-option active" data-size="1024x1536">1024×1536</div>
<div class="size-option" data-size="1536x1024">1536×1024</div>
<div class="size-option" data-size="auto">Auto</div>
</div>
<label>提示词</label>
<textarea id="prompt" placeholder="描述你想生成的图片...">为我生成图中角色的绘制 Q 版的,LINE 风格的半身像表情包,注意头饰要正确
彩色手绘风格,使用 4x6 布局,涵盖各种各样的常用聊天语句,或是一些有关的娱乐 meme
其他需求:不要原图复制。所有标注为手写简体中文。
生成的图片需为 2K 分辨率 16:9</textarea>
<button class="btn-generate" id="btnGenerate" onclick="generate()">✨ 生成图片</button>
</div>
<!-- 当前结果 -->
<div class="card">
<div class="result-area" id="resultArea">
<div class="placeholder-icon">🖼️</div>
<div class="placeholder-text">图片将显示在这里</div>
</div>
</div>
<!-- 历史记录 -->
<div class="card" id="historyCard">
<div class="history-header">
<h2>📚 历史记录 <span class="history-count" id="historyCount">0 张</span></h2>
<button class="btn-clear" id="btnClear" onclick="clearHistory()">🗑️ 清空</button>
</div>
<div id="historyGrid" class="history-grid">
<div class="history-empty">还没有生成过图片</div>
</div>
</div>
<footer>
Powered by <a href="https://edgeone.ai" target="_blank">EdgeOne Pages</a> · API 调用由浏览器直连,密钥不会经过第三方 · 历史图片存储在浏览器 IndexedDB 中
</footer>
</div>
<!-- 全屏预览 -->
<div class="lightbox" id="lightbox" onclick="closeLightbox()">
<button class="lightbox-close" onclick="closeLightbox()">✕</button>
<img id="lightboxImg" src="" alt="Preview" />
</div>
<script>
let selectedSize = '1024x1536';
let history = [];
let activeIndex = -1;
const DB_NAME = 'AIImageGenerator';
const DB_VERSION = 1;
const STORE_NAME = 'images';
// ── IndexedDB ──
function openDB() {
return new Promise((resolve, reject) => {
const req = indexedDB.open(DB_NAME, DB_VERSION);
req.onupgradeneeded = (e) => {
const db = e.target.result;
if (!db.objectStoreNames.contains(STORE_NAME)) {
db.createObjectStore(STORE_NAME, { keyPath: 'id', autoIncrement: true });
}
};
req.onsuccess = () => resolve(req.result);
req.onerror = () => reject(req.error);
});
}
async function saveToDB(item) {
const db = await openDB();
return new Promise((resolve, reject) => {
const tx = db.transaction(STORE_NAME, 'readwrite');
const store = tx.objectStore(STORE_NAME);
const req = store.add(item);
req.onsuccess = () => resolve(req.result);
req.onerror = () => reject(req.error);
});
}
async function loadAllFromDB() {
const db = await openDB();
return new Promise((resolve, reject) => {
const tx = db.transaction(STORE_NAME, 'readonly');
const store = tx.objectStore(STORE_NAME);
const req = store.getAll();
req.onsuccess = () => resolve(req.result);
req.onerror = () => reject(req.error);
});
}
async function deleteFromDB(id) {
const db = await openDB();
return new Promise((resolve, reject) => {
const tx = db.transaction(STORE_NAME, 'readwrite');
const store = tx.objectStore(STORE_NAME);
const req = store.delete(id);
req.onsuccess = () => resolve();
req.onerror = () => reject(req.error);
});
}
async function clearDB() {
const db = await openDB();
return new Promise((resolve, reject) => {
const tx = db.transaction(STORE_NAME, 'readwrite');
const store = tx.objectStore(STORE_NAME);
const req = store.clear();
req.onsuccess = () => resolve();
req.onerror = () => reject(req.error);
});
}
// ── 初始化 ──
document.querySelectorAll('.size-option').forEach(el => {
el.addEventListener('click', () => {
document.querySelectorAll('.size-option').forEach(e => e.classList.remove('active'));
el.classList.add('active');
selectedSize = el.dataset.size;
});
});
async function init() {
try {
history = await loadAllFromDB();
renderHistory();
if (history.length > 0) {
showImage(history.length - 1);
}
} catch (e) {
console.warn('IndexedDB load failed:', e);
}
}
init();
// ── 渲染历史 ──
function renderHistory() {
const grid = document.getElementById('historyGrid');
const count = document.getElementById('historyCount');
count.textContent = history.length + ' 张';
if (history.length === 0) {
grid.innerHTML = '<div class="history-empty">还没有生成过图片</div>';
return;
}
// 按时间倒序显示(最新在前)
const sorted = [...history].reverse();
grid.innerHTML = sorted.map((item, ri) => {
const realIndex = history.length - 1 - ri;
const time = new Date(item.timestamp).toLocaleString('zh-CN', { month:'short', day:'numeric', hour:'2-digit', minute:'2-digit' });
const shortPrompt = item.prompt.length > 20 ? item.prompt.slice(0, 20) + '…' : item.prompt;
return `
<div class="history-item ${realIndex === activeIndex ? 'active' : ''}" onclick="showImage(${realIndex})">
<span class="item-index">#${realIndex + 1}</span>
<img src="data:image/png;base64,${item.base64}" alt="${shortPrompt}" loading="lazy" />
<div class="item-meta">
<span>${time}</span>
<button class="btn-del" onclick="event.stopPropagation();deleteImage(${realIndex})" title="删除">✕</button>
</div>
</div>
`;
}).join('');
}
function showImage(index) {
if (index < 0 || index >= history.length) return;
activeIndex = index;
const item = history[index];
const area = document.getElementById('resultArea');
const shortPrompt = item.prompt.length > 60 ? item.prompt.slice(0, 60) + '…' : item.prompt;
area.innerHTML = `
<img src="data:image/png;base64,${item.base64}" alt="Generated Image" onclick="openLightbox(${index})" title="点击查看大图" />
<div style="margin-top:10px;color:#888;font-size:0.8em;max-width:500px;text-align:center">${shortPrompt}</div>
<div class="result-actions">
<button class="btn-action" onclick="downloadImage(${index})">💾 下载</button>
<button class="btn-action" onclick="copyPrompt(${index})">📋 复制提示词</button>
<button class="btn-action" onclick="openLightbox(${index})">🔍 大图</button>
</div>
`;
renderHistory();
}
// ── 生成 ──
function setGenerating(on) {
const btn = document.getElementById('btnGenerate');
const area = document.getElementById('resultArea');
btn.disabled = on;
if (on) {
area.innerHTML = '<div class="spinner"></div><div class="loading-text">正在生成图片,请稍候...</div>';
}
}
function showError(msg) {
const area = document.getElementById('resultArea');
area.innerHTML = `<div class="placeholder-icon">⚠️</div><div class="error-msg">${msg}</div>`;
}
async function generate() {
const apiKey = document.getElementById('apiKey').value.trim();
const baseUrl = document.getElementById('baseUrl').value.trim();
const model = document.getElementById('model').value.trim();
const prompt = document.getElementById('prompt').value.trim();
if (!apiKey) { showError('请输入 API Key'); return; }
if (!baseUrl) { showError('请输入 Base URL'); return; }
if (!prompt) { showError('请输入提示词'); return; }
setGenerating(true);
try {
const url = baseUrl.replace(/\/+$/, '') + '/responses';
const body = {
model: model || 'gpt-5.4',
input: prompt,
tools: [{ type: 'image_generation' }]
};
if (selectedSize !== 'auto') {
body.tools[0].size = selectedSize;
}
const resp = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${apiKey}`
},
body: JSON.stringify(body)
});
if (!resp.ok) {
const errText = await resp.text();
let errMsg = `HTTP ${resp.status}`;
try { errMsg += ': ' + JSON.parse(errText).error?.message || errText; } catch { errMsg += ': ' + errText.slice(0, 300); }
throw new Error(errMsg);
}
const data = await resp.json();
const imageOutputs = (data.output || []).filter(o => o.type === 'image_generation_call');
if (!imageOutputs.length) {
throw new Error('API 返回成功但未包含生成的图片。响应: ' + JSON.stringify(data).slice(0, 500));
}
const base64 = imageOutputs[0].result;
const item = {
base64,
prompt,
model: model || 'gpt-5.4',
size: selectedSize,
timestamp: Date.now()
};
// 存入 IndexedDB
try {
const id = await saveToDB(item);
item.id = id;
} catch (e) {
console.warn('IndexedDB save failed, using memory only:', e);
}
history.push(item);
showImage(history.length - 1);
} catch (err) {
showError(err.message);
} finally {
document.getElementById('btnGenerate').disabled = false;
}
}
// ── 操作 ──
function downloadImage(index) {
if (index < 0 || index >= history.length) return;
const item = history[index];
const a = document.createElement('a');
a.href = 'data:image/png;base64,' + item.base64;
a.download = 'ai-image-' + new Date(item.timestamp).toISOString().slice(0,10) + '-' + (index + 1) + '.png';
a.click();
}
function copyPrompt(index) {
if (index < 0 || index >= history.length) return;
navigator.clipboard.writeText(history[index].prompt).then(() => {
const btn = event.target;
const orig = btn.textContent;
btn.textContent = '✅ 已复制';
setTimeout(() => btn.textContent = orig, 1500);
});
}
async function deleteImage(index) {
if (index < 0 || index >= history.length) return;
const item = history[index];
try { await deleteFromDB(item.id); } catch (e) { console.warn(e); }
history.splice(index, 1);
if (activeIndex === index) {
activeIndex = history.length > 0 ? Math.min(index, history.length - 1) : -1;
if (activeIndex >= 0) showImage(activeIndex);
else document.getElementById('resultArea').innerHTML = '<div class="placeholder-icon">🖼️</div><div class="placeholder-text">图片将显示在这里</div>';
} else if (activeIndex > index) {
activeIndex--;
}
renderHistory();
}
async function clearHistory() {
if (!confirm('确定清空所有历史记录?此操作不可撤销。')) return;
try { await clearDB(); } catch (e) { console.warn(e); }
history = [];
activeIndex = -1;
document.getElementById('resultArea').innerHTML = '<div class="placeholder-icon">🖼️</div><div class="placeholder-text">图片将显示在这里</div>';
renderHistory();
}
// ── 全屏预览 ──
function openLightbox(index) {
if (index < 0 || index >= history.length) return;
const img = document.getElementById('lightboxImg');
img.src = 'data:image/png;base64,' + history[index].base64;
document.getElementById('lightbox').classList.add('show');
document.body.style.overflow = 'hidden';
}
function closeLightbox() {
document.getElementById('lightbox').classList.remove('show');
document.body.style.overflow = '';
}
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape') closeLightbox();
});
// ── 保存/恢复设置 ──
['apiKey', 'baseUrl', 'model'].forEach(id => {
const el = document.getElementById(id);
const saved = localStorage.getItem('imggen_' + id);
if (saved) el.value = saved;
el.addEventListener('change', () => localStorage.setItem('imggen_' + id, el.value));
});
</script>
</body>
</html>
image577×115 8.02 KB
至于怎么发布就是告诉它需要用edgeone发布这个静态页即可,当然你也可以双击这个h5页面在本地使用。
特性列表:
| # | 特性 | 分类 | 说明 |
|---|---|---|---|
| 1 | 数据本地化 | 隐私 | 所有数据仅存储在浏览器本地(IndexedDB + localStorage),不经过任何第三方服务器。API Key、生成记录、图片数据全部留在用户设备上 |
| 2 | P2P 直连 API | 安全 | 浏览器直接连接用户配置的 API 端点,无需中间代理。密钥和请求内容不经过页面服务器中转 |
| 3 | 历史持久化 | 存储 | 基于 IndexedDB 存储所有生成记录,刷新页面、关闭浏览器后重新打开仍保留全部图片和提示词 |
| 4 | 缩略图画廊 | 浏览 | 按时间倒序展示所有历史图片的缩略图网格,最新生成排在最前,一键回溯所有作品 |
| 5 | 全屏大图预览 | 查看 | 点击任意图片即可全屏查看高清原图,支持 ESC 键快速关闭 |
| 6 | 多尺寸支持 | 灵活 | 内置 1024×1024 / 1024×1536 / 1536×1024 / Auto 四种尺寸预设 |
| 7 | 配置记忆 | 便捷 | 自动保存 Base URL、Model、API Key 到 localStorage,下次打开无需重新填写 |
| 8 | 提示词复用 | 效率 | 一键复制历史图片的 prompt 提示词,快速填入输入框进行微调或重新生成 |
| 9 | 独立下载 | 导出 | 每张图片支持单独下载为 PNG 文件,文件名自动包含日期和序号 |
| 10 | 灵活管理 | 控制 | 支持单条删除和一键清空全部历史,删除前有二次确认防止误操作 |
| 11 | 兼容 OpenAI 协议 | 通用 | 支持所有兼容 OpenAI Responses API 格式的服务商,填入 Base URL 即可切换 |
| 12 | 响应式布局 | 体验 | 自适应桌面和移动端屏幕,画廊网格自动调整列数 |
灵感来自于:周五使用codex 直接发提示词也能出图,当然站内也有人分享原理了。
好比: 没有gpt-image-2,也可以用gpt-5.2进行生图 - 开发调优 / 开发调优, Lv1 - LINUX DO
any 上的消耗图
image2100×298 32.5 KB
因为是非流 生图比较慢,耐心等待即可。
image1263×863 96.6 KB
更新了openai官网支持的参数
AI 图片生成器
--【壹】--:
佬,我发现不管图片尺寸选2K还是4K,生成出来的分辨率一直都是1672×941
--【贰】--:
好用,感谢!请问会考虑加入参考图片功能吗
--【叁】--:
浏览器cors的问题导致的,但是咋处理我也不会(,看看有没有大佬能解决
--【肆】--:
用any是不是不能指定2k,4k。我看传入参数也没用。还是auto和1k
--【伍】--:
能出2k4k或者0.5k这种吗,还是智能出1k的
--【陆】--:
为什么我使用别的第三方中转站都会提示这个,测试了好几个了
Screenshot2026-04-27-20-41-18-7216c8430dcd18ddacf572a6564ace01501240×2772 212 KB
--【柒】--:
感觉any的gpt,比claude便宜好多
--【捌】--:
为什么模型选择是5.3呢?
不太懂这个,可以在codex中用吗
--【玖】--:
右键选择查看网页源代码,或者ctrl+u。
--【拾】--:
原理就是提示词+工具调用触发底层调用gpt-image-2模型返图,为什么是5.3因为anyrouter里面只有5.3和5.0,支持 OpenAI Responses API 的5.X 模型应该都是可以的。
--【拾壹】--: 唐钰逍遥:
更新了openai官网支持的参数
经测试,完全可用,好用,赞
这个“更新了openai官网支持的参数” 的版本能提供HTML源码吗?谢谢
--【拾贰】--: 罗季安:
右键选择查看网页源代码,或者ctrl+u。
没注意看代码,贴文给出的已经是改过版的源码HTML了,我的疏忽
--【拾叁】--:
更了一版,支持了所有官网的参数。
AI 图片生成器
--【拾肆】--:
没有用any,用的其他第三方的,但是报错了佬
image1920×1066 114 KB
--【拾伍】--: 唐钰逍遥:
内置 1024×1024 / 1024×1536 / 1536×1024 / Auto 四种尺寸预设
为啥这个选了没啥用呢,是无法约束到么?。
--【拾陆】--:
佬,这个能输入参考图嘛,给他一张参考图然后让他按照参考图生图
--【拾柒】--:
嗯 gpt之前一直没人用,之前一直没法用于codex。
--【拾捌】--:
都行,参照源码,你改改你想要的参数就行。
--【拾玖】--:
真的好用
image1024×1536 599 KB
任意第三方API 公益站
image596×902 112 KB
楼主伟大
生成这张图片花费0.14元,离了谱的便宜…
能直接用的地址,只用填上你的key即可。
AI 图片生成器
效果图
image2348×1878 410 KB
下面是教程以及源码
在你的claude code 中安装如下的mcp
“mcpServers”: {
“edgeone-pages-mcp-server”: {
“url”: “https://mcp-on-edge.edgeone.app/mcp-server”
}
}
ps:使用cc desktop的需要重启desktop,才能使用部署好的edgeone mcp。
接下来就是你按照如下代码生成h5网页并使用mcp发布到edgeone,服务端会给你返回一个地址。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AI 图片生成器</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background: linear-gradient(135deg, #0f0c29, #302b63, #24243e);
min-height: 100vh;
color: #e0e0e0;
}
.container {
max-width: 760px;
margin: 0 auto;
padding: 40px 20px;
}
h1 {
text-align: center;
font-size: 2em;
margin-bottom: 8px;
background: linear-gradient(90deg, #667eea, #764ba2, #f093fb);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.subtitle {
text-align: center;
color: #888;
margin-bottom: 36px;
font-size: 0.95em;
}
.card {
background: rgba(255,255,255,0.05);
border: 1px solid rgba(255,255,255,0.1);
border-radius: 16px;
padding: 28px;
margin-bottom: 24px;
backdrop-filter: blur(10px);
}
label {
display: block;
font-size: 0.85em;
color: #aaa;
margin-bottom: 6px;
font-weight: 500;
}
input, textarea, select {
width: 100%;
padding: 12px 14px;
border: 1px solid rgba(255,255,255,0.15);
border-radius: 10px;
background: rgba(0,0,0,0.3);
color: #f0f0f0;
font-size: 0.95em;
margin-bottom: 18px;
transition: border-color 0.2s;
font-family: inherit;
}
input:focus, textarea:focus {
outline: none;
border-color: #667eea;
}
textarea {
resize: vertical;
min-height: 80px;
}
.row {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 16px;
}
.btn-generate {
width: 100%;
padding: 14px;
border: none;
border-radius: 12px;
font-size: 1.05em;
font-weight: 600;
cursor: pointer;
background: linear-gradient(135deg, #667eea, #764ba2);
color: white;
transition: transform 0.15s, box-shadow 0.2s, opacity 0.2s;
margin-top: 4px;
}
.btn-generate:hover { transform: translateY(-1px); box-shadow: 0 6px 24px rgba(102,126,234,0.4); }
.btn-generate:active { transform: translateY(0); }
.btn-generate:disabled { opacity: 0.6; cursor: not-allowed; transform: none; box-shadow: none; }
.result-area {
text-align: center;
min-height: 120px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.result-area img {
max-width: 100%;
max-height: 520px;
border-radius: 12px;
box-shadow: 0 8px 32px rgba(0,0,0,0.4);
cursor: pointer;
transition: transform 0.2s;
}
.result-area img:hover { transform: scale(1.01); }
.result-actions {
display: flex;
gap: 10px;
margin-top: 16px;
flex-wrap: wrap;
justify-content: center;
}
.btn-action {
padding: 10px 28px;
border: 1px solid rgba(255,255,255,0.2);
border-radius: 10px;
background: rgba(255,255,255,0.08);
color: #e0e0e0;
cursor: pointer;
font-size: 0.9em;
transition: background 0.2s;
}
.btn-action:hover { background: rgba(255,255,255,0.15); }
.spinner {
width: 48px; height: 48px;
border: 4px solid rgba(255,255,255,0.1);
border-top-color: #667eea;
border-radius: 50%;
animation: spin 0.8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
.loading-text {
margin-top: 16px;
color: #aaa;
font-size: 0.9em;
}
.placeholder-icon {
font-size: 3em;
margin-bottom: 12px;
opacity: 0.3;
}
.placeholder-text {
color: #555;
font-size: 0.9em;
}
.error-msg {
color: #ff6b6b;
background: rgba(255,107,107,0.1);
border: 1px solid rgba(255,107,107,0.2);
border-radius: 10px;
padding: 14px;
margin-top: 12px;
font-size: 0.9em;
text-align: left;
word-break: break-all;
}
.size-selector {
display: flex;
gap: 8px;
margin-bottom: 18px;
flex-wrap: wrap;
}
.size-option {
padding: 8px 16px;
border: 1px solid rgba(255,255,255,0.15);
border-radius: 8px;
background: rgba(0,0,0,0.2);
color: #ccc;
cursor: pointer;
font-size: 0.85em;
transition: all 0.2s;
}
.size-option:hover { border-color: #667eea; color: #fff; }
.size-option.active { border-color: #667eea; background: rgba(102,126,234,0.2); color: #fff; }
/* 历史记录区域 */
.history-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 16px;
}
.history-header h2 {
font-size: 1.1em;
color: #aaa;
}
.history-count {
font-size: 0.8em;
color: #666;
background: rgba(255,255,255,0.05);
padding: 4px 12px;
border-radius: 20px;
}
.btn-clear {
padding: 6px 16px;
border: 1px solid rgba(255,100,100,0.3);
border-radius: 8px;
background: rgba(255,100,100,0.08);
color: #ff8888;
cursor: pointer;
font-size: 0.8em;
transition: all 0.2s;
}
.btn-clear:hover { background: rgba(255,100,100,0.15); border-color: rgba(255,100,100,0.5); }
.history-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
gap: 12px;
}
.history-item {
position: relative;
border-radius: 12px;
overflow: hidden;
cursor: pointer;
border: 2px solid transparent;
transition: all 0.2s;
aspect-ratio: 1;
background: rgba(0,0,0,0.3);
}
.history-item:hover {
border-color: #667eea;
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(0,0,0,0.4);
}
.history-item.active {
border-color: #f093fb;
box-shadow: 0 0 0 2px rgba(240,147,251,0.3);
}
.history-item img {
width: 100%;
height: 100%;
object-fit: cover;
}
.history-item .item-meta {
position: absolute;
bottom: 0;
left: 0;
right: 0;
padding: 6px 8px;
background: linear-gradient(transparent, rgba(0,0,0,0.8));
font-size: 0.7em;
color: #ccc;
display: flex;
justify-content: space-between;
align-items: center;
}
.history-item .item-index {
position: absolute;
top: 6px;
left: 6px;
background: rgba(0,0,0,0.6);
color: #aaa;
font-size: 0.7em;
padding: 2px 8px;
border-radius: 10px;
}
.history-item .btn-del {
background: none;
border: none;
color: #ff6b6b;
cursor: pointer;
font-size: 1em;
padding: 0 4px;
opacity: 0;
transition: opacity 0.2s;
}
.history-item:hover .btn-del { opacity: 1; }
.history-empty {
text-align: center;
padding: 40px 20px;
color: #555;
}
/* 全屏预览 */
.lightbox {
display: none;
position: fixed;
inset: 0;
background: rgba(0,0,0,0.92);
z-index: 1000;
justify-content: center;
align-items: center;
cursor: zoom-out;
}
.lightbox.show { display: flex; }
.lightbox img {
max-width: 95vw;
max-height: 92vh;
border-radius: 8px;
box-shadow: 0 12px 48px rgba(0,0,0,0.6);
}
.lightbox-close {
position: fixed;
top: 20px;
right: 24px;
background: rgba(255,255,255,0.1);
border: 1px solid rgba(255,255,255,0.2);
color: white;
width: 40px;
height: 40px;
border-radius: 50%;
font-size: 1.2em;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: background 0.2s;
}
.lightbox-close:hover { background: rgba(255,255,255,0.2); }
footer {
text-align: center;
color: #444;
font-size: 0.8em;
margin-top: 40px;
}
footer a { color: #667eea; text-decoration: none; }
</style>
</head>
<body>
<div class="container">
<h1>🎨 AI 图片生成器</h1>
<p class="subtitle">基于 OpenAI Responses API,在浏览器中直接生成图片</p>
<div class="card">
<div class="row">
<div>
<label>Base URL</label>
<input type="text" id="baseUrl" placeholder="https://api.openai.com/v1" value="https://anyrouter.top/v1">
</div>
<div>
<label>Model</label>
<input type="text" id="model" placeholder="gpt-5.4" value="gpt-5.3-codex">
</div>
</div>
<label>API Key</label>
<input type="password" id="apiKey" placeholder="sk-...(密钥仅在浏览器本地使用,不会上传)">
<label>图片尺寸</label>
<div class="size-selector" id="sizeSelector">
<div class="size-option" data-size="1024x1024">1024×1024</div>
<div class="size-option active" data-size="1024x1536">1024×1536</div>
<div class="size-option" data-size="1536x1024">1536×1024</div>
<div class="size-option" data-size="auto">Auto</div>
</div>
<label>提示词</label>
<textarea id="prompt" placeholder="描述你想生成的图片...">为我生成图中角色的绘制 Q 版的,LINE 风格的半身像表情包,注意头饰要正确
彩色手绘风格,使用 4x6 布局,涵盖各种各样的常用聊天语句,或是一些有关的娱乐 meme
其他需求:不要原图复制。所有标注为手写简体中文。
生成的图片需为 2K 分辨率 16:9</textarea>
<button class="btn-generate" id="btnGenerate" onclick="generate()">✨ 生成图片</button>
</div>
<!-- 当前结果 -->
<div class="card">
<div class="result-area" id="resultArea">
<div class="placeholder-icon">🖼️</div>
<div class="placeholder-text">图片将显示在这里</div>
</div>
</div>
<!-- 历史记录 -->
<div class="card" id="historyCard">
<div class="history-header">
<h2>📚 历史记录 <span class="history-count" id="historyCount">0 张</span></h2>
<button class="btn-clear" id="btnClear" onclick="clearHistory()">🗑️ 清空</button>
</div>
<div id="historyGrid" class="history-grid">
<div class="history-empty">还没有生成过图片</div>
</div>
</div>
<footer>
Powered by <a href="https://edgeone.ai" target="_blank">EdgeOne Pages</a> · API 调用由浏览器直连,密钥不会经过第三方 · 历史图片存储在浏览器 IndexedDB 中
</footer>
</div>
<!-- 全屏预览 -->
<div class="lightbox" id="lightbox" onclick="closeLightbox()">
<button class="lightbox-close" onclick="closeLightbox()">✕</button>
<img id="lightboxImg" src="" alt="Preview" />
</div>
<script>
let selectedSize = '1024x1536';
let history = [];
let activeIndex = -1;
const DB_NAME = 'AIImageGenerator';
const DB_VERSION = 1;
const STORE_NAME = 'images';
// ── IndexedDB ──
function openDB() {
return new Promise((resolve, reject) => {
const req = indexedDB.open(DB_NAME, DB_VERSION);
req.onupgradeneeded = (e) => {
const db = e.target.result;
if (!db.objectStoreNames.contains(STORE_NAME)) {
db.createObjectStore(STORE_NAME, { keyPath: 'id', autoIncrement: true });
}
};
req.onsuccess = () => resolve(req.result);
req.onerror = () => reject(req.error);
});
}
async function saveToDB(item) {
const db = await openDB();
return new Promise((resolve, reject) => {
const tx = db.transaction(STORE_NAME, 'readwrite');
const store = tx.objectStore(STORE_NAME);
const req = store.add(item);
req.onsuccess = () => resolve(req.result);
req.onerror = () => reject(req.error);
});
}
async function loadAllFromDB() {
const db = await openDB();
return new Promise((resolve, reject) => {
const tx = db.transaction(STORE_NAME, 'readonly');
const store = tx.objectStore(STORE_NAME);
const req = store.getAll();
req.onsuccess = () => resolve(req.result);
req.onerror = () => reject(req.error);
});
}
async function deleteFromDB(id) {
const db = await openDB();
return new Promise((resolve, reject) => {
const tx = db.transaction(STORE_NAME, 'readwrite');
const store = tx.objectStore(STORE_NAME);
const req = store.delete(id);
req.onsuccess = () => resolve();
req.onerror = () => reject(req.error);
});
}
async function clearDB() {
const db = await openDB();
return new Promise((resolve, reject) => {
const tx = db.transaction(STORE_NAME, 'readwrite');
const store = tx.objectStore(STORE_NAME);
const req = store.clear();
req.onsuccess = () => resolve();
req.onerror = () => reject(req.error);
});
}
// ── 初始化 ──
document.querySelectorAll('.size-option').forEach(el => {
el.addEventListener('click', () => {
document.querySelectorAll('.size-option').forEach(e => e.classList.remove('active'));
el.classList.add('active');
selectedSize = el.dataset.size;
});
});
async function init() {
try {
history = await loadAllFromDB();
renderHistory();
if (history.length > 0) {
showImage(history.length - 1);
}
} catch (e) {
console.warn('IndexedDB load failed:', e);
}
}
init();
// ── 渲染历史 ──
function renderHistory() {
const grid = document.getElementById('historyGrid');
const count = document.getElementById('historyCount');
count.textContent = history.length + ' 张';
if (history.length === 0) {
grid.innerHTML = '<div class="history-empty">还没有生成过图片</div>';
return;
}
// 按时间倒序显示(最新在前)
const sorted = [...history].reverse();
grid.innerHTML = sorted.map((item, ri) => {
const realIndex = history.length - 1 - ri;
const time = new Date(item.timestamp).toLocaleString('zh-CN', { month:'short', day:'numeric', hour:'2-digit', minute:'2-digit' });
const shortPrompt = item.prompt.length > 20 ? item.prompt.slice(0, 20) + '…' : item.prompt;
return `
<div class="history-item ${realIndex === activeIndex ? 'active' : ''}" onclick="showImage(${realIndex})">
<span class="item-index">#${realIndex + 1}</span>
<img src="data:image/png;base64,${item.base64}" alt="${shortPrompt}" loading="lazy" />
<div class="item-meta">
<span>${time}</span>
<button class="btn-del" onclick="event.stopPropagation();deleteImage(${realIndex})" title="删除">✕</button>
</div>
</div>
`;
}).join('');
}
function showImage(index) {
if (index < 0 || index >= history.length) return;
activeIndex = index;
const item = history[index];
const area = document.getElementById('resultArea');
const shortPrompt = item.prompt.length > 60 ? item.prompt.slice(0, 60) + '…' : item.prompt;
area.innerHTML = `
<img src="data:image/png;base64,${item.base64}" alt="Generated Image" onclick="openLightbox(${index})" title="点击查看大图" />
<div style="margin-top:10px;color:#888;font-size:0.8em;max-width:500px;text-align:center">${shortPrompt}</div>
<div class="result-actions">
<button class="btn-action" onclick="downloadImage(${index})">💾 下载</button>
<button class="btn-action" onclick="copyPrompt(${index})">📋 复制提示词</button>
<button class="btn-action" onclick="openLightbox(${index})">🔍 大图</button>
</div>
`;
renderHistory();
}
// ── 生成 ──
function setGenerating(on) {
const btn = document.getElementById('btnGenerate');
const area = document.getElementById('resultArea');
btn.disabled = on;
if (on) {
area.innerHTML = '<div class="spinner"></div><div class="loading-text">正在生成图片,请稍候...</div>';
}
}
function showError(msg) {
const area = document.getElementById('resultArea');
area.innerHTML = `<div class="placeholder-icon">⚠️</div><div class="error-msg">${msg}</div>`;
}
async function generate() {
const apiKey = document.getElementById('apiKey').value.trim();
const baseUrl = document.getElementById('baseUrl').value.trim();
const model = document.getElementById('model').value.trim();
const prompt = document.getElementById('prompt').value.trim();
if (!apiKey) { showError('请输入 API Key'); return; }
if (!baseUrl) { showError('请输入 Base URL'); return; }
if (!prompt) { showError('请输入提示词'); return; }
setGenerating(true);
try {
const url = baseUrl.replace(/\/+$/, '') + '/responses';
const body = {
model: model || 'gpt-5.4',
input: prompt,
tools: [{ type: 'image_generation' }]
};
if (selectedSize !== 'auto') {
body.tools[0].size = selectedSize;
}
const resp = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${apiKey}`
},
body: JSON.stringify(body)
});
if (!resp.ok) {
const errText = await resp.text();
let errMsg = `HTTP ${resp.status}`;
try { errMsg += ': ' + JSON.parse(errText).error?.message || errText; } catch { errMsg += ': ' + errText.slice(0, 300); }
throw new Error(errMsg);
}
const data = await resp.json();
const imageOutputs = (data.output || []).filter(o => o.type === 'image_generation_call');
if (!imageOutputs.length) {
throw new Error('API 返回成功但未包含生成的图片。响应: ' + JSON.stringify(data).slice(0, 500));
}
const base64 = imageOutputs[0].result;
const item = {
base64,
prompt,
model: model || 'gpt-5.4',
size: selectedSize,
timestamp: Date.now()
};
// 存入 IndexedDB
try {
const id = await saveToDB(item);
item.id = id;
} catch (e) {
console.warn('IndexedDB save failed, using memory only:', e);
}
history.push(item);
showImage(history.length - 1);
} catch (err) {
showError(err.message);
} finally {
document.getElementById('btnGenerate').disabled = false;
}
}
// ── 操作 ──
function downloadImage(index) {
if (index < 0 || index >= history.length) return;
const item = history[index];
const a = document.createElement('a');
a.href = 'data:image/png;base64,' + item.base64;
a.download = 'ai-image-' + new Date(item.timestamp).toISOString().slice(0,10) + '-' + (index + 1) + '.png';
a.click();
}
function copyPrompt(index) {
if (index < 0 || index >= history.length) return;
navigator.clipboard.writeText(history[index].prompt).then(() => {
const btn = event.target;
const orig = btn.textContent;
btn.textContent = '✅ 已复制';
setTimeout(() => btn.textContent = orig, 1500);
});
}
async function deleteImage(index) {
if (index < 0 || index >= history.length) return;
const item = history[index];
try { await deleteFromDB(item.id); } catch (e) { console.warn(e); }
history.splice(index, 1);
if (activeIndex === index) {
activeIndex = history.length > 0 ? Math.min(index, history.length - 1) : -1;
if (activeIndex >= 0) showImage(activeIndex);
else document.getElementById('resultArea').innerHTML = '<div class="placeholder-icon">🖼️</div><div class="placeholder-text">图片将显示在这里</div>';
} else if (activeIndex > index) {
activeIndex--;
}
renderHistory();
}
async function clearHistory() {
if (!confirm('确定清空所有历史记录?此操作不可撤销。')) return;
try { await clearDB(); } catch (e) { console.warn(e); }
history = [];
activeIndex = -1;
document.getElementById('resultArea').innerHTML = '<div class="placeholder-icon">🖼️</div><div class="placeholder-text">图片将显示在这里</div>';
renderHistory();
}
// ── 全屏预览 ──
function openLightbox(index) {
if (index < 0 || index >= history.length) return;
const img = document.getElementById('lightboxImg');
img.src = 'data:image/png;base64,' + history[index].base64;
document.getElementById('lightbox').classList.add('show');
document.body.style.overflow = 'hidden';
}
function closeLightbox() {
document.getElementById('lightbox').classList.remove('show');
document.body.style.overflow = '';
}
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape') closeLightbox();
});
// ── 保存/恢复设置 ──
['apiKey', 'baseUrl', 'model'].forEach(id => {
const el = document.getElementById(id);
const saved = localStorage.getItem('imggen_' + id);
if (saved) el.value = saved;
el.addEventListener('change', () => localStorage.setItem('imggen_' + id, el.value));
});
</script>
</body>
</html>
image577×115 8.02 KB
至于怎么发布就是告诉它需要用edgeone发布这个静态页即可,当然你也可以双击这个h5页面在本地使用。
特性列表:
| # | 特性 | 分类 | 说明 |
|---|---|---|---|
| 1 | 数据本地化 | 隐私 | 所有数据仅存储在浏览器本地(IndexedDB + localStorage),不经过任何第三方服务器。API Key、生成记录、图片数据全部留在用户设备上 |
| 2 | P2P 直连 API | 安全 | 浏览器直接连接用户配置的 API 端点,无需中间代理。密钥和请求内容不经过页面服务器中转 |
| 3 | 历史持久化 | 存储 | 基于 IndexedDB 存储所有生成记录,刷新页面、关闭浏览器后重新打开仍保留全部图片和提示词 |
| 4 | 缩略图画廊 | 浏览 | 按时间倒序展示所有历史图片的缩略图网格,最新生成排在最前,一键回溯所有作品 |
| 5 | 全屏大图预览 | 查看 | 点击任意图片即可全屏查看高清原图,支持 ESC 键快速关闭 |
| 6 | 多尺寸支持 | 灵活 | 内置 1024×1024 / 1024×1536 / 1536×1024 / Auto 四种尺寸预设 |
| 7 | 配置记忆 | 便捷 | 自动保存 Base URL、Model、API Key 到 localStorage,下次打开无需重新填写 |
| 8 | 提示词复用 | 效率 | 一键复制历史图片的 prompt 提示词,快速填入输入框进行微调或重新生成 |
| 9 | 独立下载 | 导出 | 每张图片支持单独下载为 PNG 文件,文件名自动包含日期和序号 |
| 10 | 灵活管理 | 控制 | 支持单条删除和一键清空全部历史,删除前有二次确认防止误操作 |
| 11 | 兼容 OpenAI 协议 | 通用 | 支持所有兼容 OpenAI Responses API 格式的服务商,填入 Base URL 即可切换 |
| 12 | 响应式布局 | 体验 | 自适应桌面和移动端屏幕,画廊网格自动调整列数 |
灵感来自于:周五使用codex 直接发提示词也能出图,当然站内也有人分享原理了。
好比: 没有gpt-image-2,也可以用gpt-5.2进行生图 - 开发调优 / 开发调优, Lv1 - LINUX DO
any 上的消耗图
image2100×298 32.5 KB
因为是非流 生图比较慢,耐心等待即可。
image1263×863 96.6 KB
更新了openai官网支持的参数
AI 图片生成器
--【壹】--:
佬,我发现不管图片尺寸选2K还是4K,生成出来的分辨率一直都是1672×941
--【贰】--:
好用,感谢!请问会考虑加入参考图片功能吗
--【叁】--:
浏览器cors的问题导致的,但是咋处理我也不会(,看看有没有大佬能解决
--【肆】--:
用any是不是不能指定2k,4k。我看传入参数也没用。还是auto和1k
--【伍】--:
能出2k4k或者0.5k这种吗,还是智能出1k的
--【陆】--:
为什么我使用别的第三方中转站都会提示这个,测试了好几个了
Screenshot2026-04-27-20-41-18-7216c8430dcd18ddacf572a6564ace01501240×2772 212 KB
--【柒】--:
感觉any的gpt,比claude便宜好多
--【捌】--:
为什么模型选择是5.3呢?
不太懂这个,可以在codex中用吗
--【玖】--:
右键选择查看网页源代码,或者ctrl+u。
--【拾】--:
原理就是提示词+工具调用触发底层调用gpt-image-2模型返图,为什么是5.3因为anyrouter里面只有5.3和5.0,支持 OpenAI Responses API 的5.X 模型应该都是可以的。
--【拾壹】--: 唐钰逍遥:
更新了openai官网支持的参数
经测试,完全可用,好用,赞
这个“更新了openai官网支持的参数” 的版本能提供HTML源码吗?谢谢
--【拾贰】--: 罗季安:
右键选择查看网页源代码,或者ctrl+u。
没注意看代码,贴文给出的已经是改过版的源码HTML了,我的疏忽
--【拾叁】--:
更了一版,支持了所有官网的参数。
AI 图片生成器
--【拾肆】--:
没有用any,用的其他第三方的,但是报错了佬
image1920×1066 114 KB
--【拾伍】--: 唐钰逍遥:
内置 1024×1024 / 1024×1536 / 1536×1024 / Auto 四种尺寸预设
为啥这个选了没啥用呢,是无法约束到么?。
--【拾陆】--:
佬,这个能输入参考图嘛,给他一张参考图然后让他按照参考图生图
--【拾柒】--:
嗯 gpt之前一直没人用,之前一直没法用于codex。
--【拾捌】--:
都行,参照源码,你改改你想要的参数就行。
--【拾玖】--:
真的好用
image1024×1536 599 KB
任意第三方API 公益站
image596×902 112 KB
楼主伟大
生成这张图片花费0.14元,离了谱的便宜…

