Files
dsProject/dsLightRag/static/LibLib/wenshengtu.html
2025-09-04 13:47:34 +08:00

627 lines
22 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>LibLib文生图生成器</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 1200px;
margin: 0 auto;
padding: 20px;
background-color: #f5f5f5;
}
.container {
background: white;
padding: 30px;
border-radius: 10px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}
h1 {
color: #333;
text-align: center;
margin-bottom: 30px;
}
.form-group {
margin-bottom: 20px;
}
label {
display: block;
margin-bottom: 5px;
font-weight: bold;
color: #555;
}
input[type="text"],
input[type="number"],
select {
width: 100%;
padding: 10px;
border: 1px solid #ddd;
border-radius: 5px;
font-size: 14px;
}
button {
background-color: #007bff;
color: white;
padding: 12px 24px;
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 16px;
margin-right: 10px;
}
button:hover {
background-color: #0056b3;
}
button:disabled {
background-color: #6c757d;
cursor: not-allowed;
}
.result {
margin-top: 30px;
padding: 20px;
background-color: #f8f9fa;
border-radius: 5px;
border-left: 4px solid #007bff;
}
.result img {
max-width: 100%;
max-height: 400px;
border: 2px solid #28a745;
border-radius: 5px;
}
.loading {
display: none;
text-align: center;
margin: 20px 0;
}
.spinner {
border: 4px solid #f3f3f3;
border-top: 4px solid #007bff;
border-radius: 50%;
width: 40px;
height: 40px;
animation: spin 1s linear infinite;
margin: 0 auto;
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.error {
color: #dc3545;
background-color: #f8d7da;
border: 1px solid #f5c6cb;
padding: 10px;
border-radius: 5px;
margin: 10px 0;
}
.success {
color: #155724;
background-color: #d4edda;
border: 1px solid #c3e6cb;
padding: 10px;
border-radius: 5px;
margin: 10px 0;
}
/* 模型选择样式 */
.model-select {
margin-bottom: 20px;
}
.model-link {
margin-top: 8px;
font-size: 14px;
color: #666;
}
.model-link a {
color: #007bff;
text-decoration: none;
}
.model-link a:hover {
text-decoration: underline;
}
/* 提示词样式 */
.prompt-textarea {
width: 100%;
height: 120px;
padding: 10px;
border: 1px solid #ddd;
border-radius: 5px;
font-size: 14px;
resize: vertical;
font-family: monospace;
}
/* 参数设置区域样式 */
.params-section {
display: flex;
flex-wrap: wrap;
gap: 15px;
margin-bottom: 20px;
}
.param-group {
flex: 1;
min-width: 200px;
}
/* 高级参数折叠区域 */
.advanced-params {
margin-top: 15px;
padding: 15px;
background-color: #f8f9fa;
border-radius: 5px;
border: 1px solid #ddd;
}
.toggle-advanced {
background: none;
border: none;
color: #007bff;
cursor: pointer;
padding: 5px 0;
font-size: 14px;
text-decoration: underline;
}
/* 图片模态框样式 */
.modal {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.9);
z-index: 1000;
justify-content: center;
align-items: center;
}
.modal-content {
max-width: 90%;
max-height: 90%;
}
.close-modal {
position: absolute;
top: 20px;
right: 30px;
color: white;
font-size: 40px;
font-weight: bold;
cursor: pointer;
}
.close-modal:hover {
color: #ccc;
}
/* 生成历史样式 */
.history-section {
margin-top: 40px;
padding-top: 20px;
border-top: 1px solid #eee;
}
.history-title {
color: #333;
margin-bottom: 15px;
font-size: 18px;
font-weight: bold;
}
.history-images {
display: flex;
flex-wrap: wrap;
gap: 15px;
justify-content: center;
}
.history-image-item {
width: calc(20% - 15px);
min-width: 120px;
cursor: pointer;
}
.history-image-item img {
width: 100%;
height: 250px;
object-fit: cover;
border-radius: 8px;
border: 2px solid #ddd;
transition: all 0.3s ease;
}
.history-image-item img:hover {
border-color: #007bff;
transform: scale(1.05);
}
/* 响应式调整 */
@media (max-width: 992px) {
.model-card {
width: calc(50% - 15px);
}
}
@media (max-width: 768px) {
.model-card {
width: 100%;
min-width: auto;
}
.model-card img {
height: 250px;
}
.param-group {
min-width: 100%;
}
}
</style>
</head>
<body>
<div class="container">
<h1>🎨 LibLib文生图生成器</h1>
<div class="form-group model-select">
<label for="modelSelect">选择生成模型:</label>
<select id="modelSelect">
<option value="custom">Dream Tech XL</option>
</select>
<div class="model-link">更多模型请访问:<a href="https://www.liblib.art/"
target="_blank">https://www.liblib.art/</a></div>
</div>
<div class="form-group">
<label for="promptInput">提示词:</label>
<textarea id="promptInput" class="prompt-textarea" placeholder="请输入描述您想要生成图片的文本...">一个美丽的女孩站在樱花树下,微笑着,阳光透过树叶洒在她的脸上,温暖而梦幻</textarea>
</div>
<div class="form-group">
<label for="negativePromptInput">反向提示词:</label>
<textarea id="negativePromptInput" class="prompt-textarea" placeholder="请输入您不希望出现在图片中的元素...">ng_deepnegative_v1_75t,(badhandv4:1.2),EasyNegative,(worst quality:2),</textarea>
</div>
<!-- 基础参数设置 -->
<div class="params-section">
<div class="param-group">
<label for="widthInput">图片宽度:</label>
<select id="widthInput">
<option value="512">512px</option>
<option value="768" selected>768px</option>
<option value="1024">1024px</option>
</select>
</div>
<div class="param-group">
<label for="heightInput">图片高度:</label>
<select id="heightInput">
<option value="512">512px</option>
<option value="768">768px</option>
<option value="1024" selected>1024px</option>
</select>
</div>
<div class="param-group">
<label for="stepsInput">迭代步数:</label>
<input type="number" id="stepsInput" value="20" min="1" max="100">
</div>
<div class="param-group">
<label for="cfgScaleInput">引导系数:</label>
<input type="number" id="cfgScaleInput" value="7" min="1" max="20" step="0.5">
</div>
</div>
<!-- 高级参数设置 -->
<div class="form-group">
<button class="toggle-advanced" onclick="toggleAdvancedParams()">显示高级参数</button>
<div id="advancedParams" class="advanced-params" style="display: none;">
<div class="params-section">
<div class="param-group">
<label for="seedInput">随机种子:</label>
<input type="number" id="seedInput" value="-1" min="-1" max="9999999999">
<small style="color: #666;">-1表示随机种子</small>
</div>
<div class="param-group">
<label for="samplerInput">采样器:</label>
<select id="samplerInput">
<option value="15">DPM++ 2M Karras</option>
<option value="14">DPM++ SDE Karras</option>
<option value="10">Euler a</option>
<option value="5">DDIM</option>
</select>
</div>
<div class="param-group">
<label for="imgCountInput">生成数量:</label>
<input type="number" id="imgCountInput" value="1" min="1" max="10">
</div>
<div class="param-group">
<label for="restoreFacesInput">面部修复:</label>
<select id="restoreFacesInput">
<option value="0">关闭</option>
<option value="1">开启</option>
</select>
</div>
</div>
<!-- 高分辨率修复参数 -->
<div class="form-group">
<label>
<input type="checkbox" id="hiResFixInput" onchange="toggleHiResFixParams()"> 启用高分辨率修复
</label>
<div id="hiResFixParams" style="display: none; margin-top: 15px;">
<div class="params-section">
<div class="param-group">
<label for="hiresStepsInput">高分辨率步数:</label>
<input type="number" id="hiresStepsInput" value="20" min="1" max="100">
</div>
<div class="param-group">
<label for="hiresDenoisingStrengthInput">去噪强度:</label>
<input type="number" id="hiresDenoisingStrengthInput" value="0.75" min="0" max="1"
step="0.05">
</div>
<div class="param-group">
<label for="resizedWidthInput">放大后宽度:</label>
<input type="number" id="resizedWidthInput" value="1024" min="64" max="2048">
</div>
<div class="param-group">
<label for="resizedHeightInput">放大后高度:</label>
<input type="number" id="resizedHeightInput" value="1536" min="64" max="2048">
</div>
</div>
</div>
</div>
</div>
</div>
<button onclick="generateImage()" id="generateBtn">生成图片</button>
<div class="loading" id="loading">
<div class="spinner"></div>
<p>正在生成中,请稍候...</p>
</div>
<div class="result" id="resultContainer" style="display: none;">
<h3>生成结果:</h3>
<div id="resultMessage"></div>
<div id="resultImage"></div>
</div>
<!-- 生成历史栏目 -->
<div class="history-section">
<h3 class="history-title">📜 生成历史</h3>
<div class="history-images">
<div class="history-image-item">
<img src="https://dsideal.obs.cn-north-1.myhuaweicloud.com/HuangHai/LibLib/679a0c38c18943e3aa340412c6fea4e0.jpg"
alt="生成历史图片1" onclick="openModal(this.src)"/>
</div>
<div class="history-image-item">
<img src="https://dsideal.obs.cn-north-1.myhuaweicloud.com/HuangHai/LibLib/5e38fb5ba0104e14b264e8c4b12d759b.jpg"
alt="生成历史图片2" onclick="openModal(this.src)"/>
</div>
<div class="history-image-item">
<img src="https://dsideal.obs.cn-north-1.myhuaweicloud.com/HuangHai/LibLib/f3b34d59e6584c96a7e50b7f58440027.jpg"
alt="生成历史图片3" onclick="openModal(this.src)"/>
</div>
<div class="history-image-item">
<img src="https://dsideal.obs.cn-north-1.myhuaweicloud.com/HuangHai/LibLib/cc21eec8398c45f9807bf9f5827c5fb1.jpg"
alt="生成历史图片4" onclick="openModal(this.src)"/>
</div>
<div class="history-image-item">
<img src="https://dsideal.obs.cn-north-1.myhuaweicloud.com/HuangHai/LibLib/1f5a3b654ae743a0acbc7b9a908dc64d.jpg"
alt="生成历史图片5" onclick="openModal(this.src)"/>
</div>
<div class="history-image-item">
<img src="https://dsideal.obs.cn-north-1.myhuaweicloud.com/HuangHai/LibLib/139b21fc79b344e480d834a70b32386c.jpg"
alt="生成历史图片6" onclick="openModal(this.src)"/>
</div>
</div>
</div>
<!-- 图片模态框 -->
<div id="imageModal" class="modal">
<span class="close-modal" onclick="closeModal()">&times;</span>
<img class="modal-content" id="modalImage">
</div>
<script>
const API_BASE = '/api/wenShengTu';
// 模态框相关变量
const modal = document.getElementById('imageModal');
const modalImage = document.getElementById('modalImage');
// 页面加载时初始化
document.addEventListener('DOMContentLoaded', function () {
// 默认选择Dream Tech XL模型
document.getElementById('modelSelect').value = 'custom';
});
// 打开模态框显示大图
function openModal(imageUrl) {
modal.style.display = 'flex';
modalImage.src = imageUrl;
}
// 关闭模态框
function closeModal() {
modal.style.display = 'none';
}
// 点击模态框背景也关闭
window.onclick = function (event) {
if (event.target == modal) {
closeModal();
}
}
// 切换高级参数显示
function toggleAdvancedParams() {
const advancedParams = document.getElementById('advancedParams');
const toggleBtn = document.querySelector('.toggle-advanced');
if (advancedParams.style.display === 'none') {
advancedParams.style.display = 'block';
toggleBtn.textContent = '隐藏高级参数';
} else {
advancedParams.style.display = 'none';
toggleBtn.textContent = '显示高级参数';
}
}
// 切换高分辨率修复参数显示
function toggleHiResFixParams() {
const hiResFixParams = document.getElementById('hiResFixParams');
const hiResFixCheckbox = document.getElementById('hiResFixInput');
if (hiResFixCheckbox.checked) {
hiResFixParams.style.display = 'block';
} else {
hiResFixParams.style.display = 'none';
}
}
// 生成图片函数
async function generateImage() {
// 获取所选模型
const selectedModel = document.getElementById('modelSelect').value;
const prompt = document.getElementById('promptInput').value.trim();
const negativePrompt = document.getElementById('negativePromptInput').value.trim();
const width = parseInt(document.getElementById('widthInput').value);
const height = parseInt(document.getElementById('heightInput').value);
const steps = parseInt(document.getElementById('stepsInput').value);
const cfgScale = parseFloat(document.getElementById('cfgScaleInput').value);
const seed = parseInt(document.getElementById('seedInput').value);
const sampler = parseInt(document.getElementById('samplerInput').value);
const imgCount = parseInt(document.getElementById('imgCountInput').value);
const restoreFaces = parseInt(document.getElementById('restoreFacesInput').value);
const hiResFix = document.getElementById('hiResFixInput').checked;
const hiresSteps = parseInt(document.getElementById('hiresStepsInput').value);
const hiresDenoisingStrength = parseFloat(document.getElementById('hiresDenoisingStrengthInput').value);
const resizedWidth = parseInt(document.getElementById('resizedWidthInput').value);
const resizedHeight = parseInt(document.getElementById('resizedHeightInput').value);
const generateBtn = document.getElementById('generateBtn');
const loading = document.getElementById('loading');
const resultContainer = document.getElementById('resultContainer');
const resultMessage = document.getElementById('resultMessage');
const resultImage = document.getElementById('resultImage');
// 验证提示词
if (!prompt) {
resultContainer.style.display = 'block';
resultMessage.innerHTML = '<div class="error">请输入提示词</div>';
return;
}
// 显示加载状态
generateBtn.disabled = true;
loading.style.display = 'block';
resultContainer.style.display = 'none';
try {
// 准备请求数据
const requestData = {
model: selectedModel,
prompt: prompt,
negative_prompt: negativePrompt,
width: width,
height: height,
steps: steps,
cfg_scale: cfgScale,
seed: seed,
sampler: sampler,
img_count: imgCount,
restore_faces: restoreFaces,
hires_fix: hiResFix
};
// 如果启用了高分辨率修复,添加相关参数
if (hiResFix) {
requestData.hires_steps = hiresSteps;
requestData.hires_denoising_strength = hiresDenoisingStrength;
requestData.resized_width = resizedWidth;
requestData.resized_height = resizedHeight;
}
// 发送请求
const response = await fetch(`${API_BASE}/generate`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(requestData)
});
const data = await response.json();
if (response.ok) {
// 显示成功结果
resultContainer.style.display = 'block';
resultMessage.innerHTML = '<div class="success">图片生成成功!</div>';
// 检查是否有图片数据
data.images=[]
data.images.push(data.obs_url)
// 处理图片数据支持Base64和URL两种格式
let imagesHtml = '';
data.images.forEach((image, index) => {
const imageId = `generatedImage_${Date.now()}_${index}`;
imagesHtml += `<img id="${imageId}" src="${image}" alt="生成图片${index + 1}" onclick="openModal(this.src)" style="max-width: 100%; margin-top: 10px; border-radius: 5px; cursor: pointer;">`;
});
resultImage.innerHTML = imagesHtml;
} else {
// 显示错误信息
resultContainer.style.display = 'block';
resultMessage.innerHTML = `<div class="error">${data.error || '生成图片失败'}</div>`;
}
} catch (error) {
// 显示网络错误
resultContainer.style.display = 'block';
resultMessage.innerHTML = `<div class="error">网络错误: ${error.message}</div>`;
} finally {
// 恢复按钮状态
generateBtn.disabled = false;
loading.style.display = 'none';
}
}
</script>
</div>
</body>
</html>