Update: Adds negative prompt functionality, deprecates legacy.php/HTML3 suppor

t in favor of HTML 4.0
This commit is contained in:
markmental 2025-01-19 18:04:41 -05:00
commit 3914c00b6d
3 changed files with 132 additions and 456 deletions

View file

@ -3,12 +3,6 @@
A minimalistic, JavaScript-free web interface, front-end and processing server for Stable Diffusion, designed specifically for being accessed by legacy systems and browsers as clients. This interface relies on the API from AUTOMATIC1111's Stable Diffusion WebUI.
## Features
Two separate interfaces are provided:
- `index.php`: HTML 4.01+ compliant interface
- `legacy.php`: HTML 3.2 compliant interface for extremely old systems
Common features across both versions:
- No JavaScript dependencies
- Lightweight and fast loading
- Support for LORA models using square bracket syntax
@ -19,12 +13,11 @@ Common features across both versions:
- Sampling steps
- CFG Scale
- Choice of sampling methods
- Negative Prompt Support (1-19-2025 Update)
## Browser Compatibility
- `index.php`: Tested working on IE4+ and comparable browsers
- `legacy.php`: Tested working on IE3 and comparable browsers
- Both versions work on modern browsers
- `index.php`: Tested working on IE4+, Netscape 4.x and above browsers (HTML 4 compliant)
## Requirements
@ -40,15 +33,14 @@ Common features across both versions:
1. Ensure you have AUTOMATIC1111's Stable Diffusion WebUI running with the `--api` flag
2. Install PHP and ImageMagick on your system
3. Copy both `index.php` and `legacy.php` to your web server directory
3. Copy both `index.php` to your web server directory
4. Ensure the directory is writable by the web server for saved prompts and generated images
5. Access through your web browser:
- Use `index.php` for HTML 4.01+ compatible browsers
- Use `legacy.php` for HTML 3.2 compatible browsers
## Usage
1. Enter your prompt in the text area
1. Enter your prompt and negative prompt if applicable in the text area
2. Configure generation parameters as needed
3. Click "Generate Image" to create your image
4. Save frequently used prompts server-side using the "Save Prompt" feature
@ -68,13 +60,6 @@ Example:
- The interface works without any client-side scripting
- All processing is done server-side
- Compatible with browsers from the late 1990s to now
- The HTML 3.2 version (`legacy.php`) provides basic functionality for extremely old mid 1990s browsers
## Why Two Versions?
- `index.php` provides a more refined interface with better styling and layout options, suitable for browsers supporting HTML 4.01+
- `legacy.php` strips down the interface to basic HTML 3.2 for maximum compatibility with vintage systems and browsers
- Both achieve the same core functionality with different levels of visual polish
## Screenshots
@ -87,7 +72,6 @@ Example:
![Screenshot 2024-12-14 143036](https://github.com/user-attachments/assets/9745d00f-57cc-4788-a17d-43782d7e6fa3)
## Contributing
Contributions are welcome! Please feel free to submit a Pull Request or fork.

201
index.php
View file

@ -5,11 +5,12 @@ header('Content-Type: text/html; charset=iso-8859-1');
$response = "";
$generated_image = "";
$prompt = "";
$width = 512;
$height = 512;
$steps = 20;
$cfg_scale = 7.5;
$sampler = "Euler";
$negative_prompt = "";
$width = 768;
$height = 768;
$steps = 35;
$cfg_scale = 3;
$sampler = "DPM++ 3M SDE";
$error_message = "";
$success_message = "";
@ -27,10 +28,13 @@ function loadSavedPrompts() {
}
// Save a new prompt
function savePrompt($prompt_text, $prompt_name) {
function savePrompt($prompt_text, $negative_prompt_text, $prompt_name) {
global $saved_prompts_file;
$prompts = loadSavedPrompts();
$prompts[$prompt_name] = $prompt_text;
$prompts[$prompt_name] = array(
'prompt' => $prompt_text,
'negative_prompt' => $negative_prompt_text
);
file_put_contents($saved_prompts_file, json_encode($prompts, JSON_PRETTY_PRINT));
}
@ -59,13 +63,15 @@ $samplers = array(
);
if ($_SERVER["REQUEST_METHOD"] == "POST") {
// All requests to the server to save or execute prompts will be POST requests to itself
// Handle prompt saving
if (isset($_POST['save_prompt']) && isset($_POST['prompt_name'])) {
$prompt_to_save = trim($_POST['prompt']);
$negative_prompt_to_save = trim($_POST['negative_prompt']);
$prompt_name = trim($_POST['prompt_name']);
if (!empty($prompt_to_save) && !empty($prompt_name)) {
savePrompt($prompt_to_save, $prompt_name);
savePrompt($prompt_to_save, $negative_prompt_to_save, $prompt_name);
$success_message = "Prompt saved successfully!";
$saved_prompts = loadSavedPrompts(); // Reload prompts
} else {
@ -75,6 +81,7 @@ if ($_SERVER["REQUEST_METHOD"] == "POST") {
// Handle image generation
else {
$prompt = isset($_POST['prompt']) ? $_POST['prompt'] : '';
$negative_prompt = isset($_POST['negative_prompt']) ? $_POST['negative_prompt'] : '';
$width = isset($_POST['width']) ? (int)$_POST['width'] : 512;
$height = isset($_POST['height']) ? (int)$_POST['height'] : 512;
$steps = isset($_POST['steps']) ? (int)$_POST['steps'] : 20;
@ -92,6 +99,7 @@ if ($_SERVER["REQUEST_METHOD"] == "POST") {
$data = array(
'prompt' => $processed_prompt,
'negative_prompt' => $negative_prompt,
'steps' => $steps,
'width' => $width,
'height' => $height,
@ -101,7 +109,7 @@ if ($_SERVER["REQUEST_METHOD"] == "POST") {
'override_settings_restore_afterwards' => true
);
// Replace 127.0.0.1 with your Stable diffusion server's IP if running externally
// Replace 127.0.0.1 with your Stable diffusion server's IP if running externally
$ch = curl_init('http://127.0.0.1:7860/sdapi/v1/txt2img');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
@ -114,66 +122,77 @@ if ($_SERVER["REQUEST_METHOD"] == "POST") {
$response = 'Error: ' . curl_error($ch);
} else {
$decoded = json_decode($result, true);
if (isset($decoded['images'][0])) {
$image_data = base64_decode($decoded['images'][0]);
if (isset($decoded['images'][0])) {
$image_data = base64_decode($decoded['images'][0]);
// Save original PNG temporarily
$temp_png = 'temp_' . time() . '_' . bin2hex(random_bytes(8)) . '.png';
file_put_contents($temp_png, $image_data);
// Save original PNG temporarily
$temp_png = 'temp_' . time() . '_' . bin2hex(random_bytes(8)) . '.png';
file_put_contents($temp_png, $image_data);
// Create output JPG filename
$generated_image = 'generated_' . time() . '_' . bin2hex(random_bytes(8)) . '.jpg';
// Create output JPG filename
$generated_image = 'generated_' . time() . '_' . bin2hex(random_bytes(8)) . '.jpg';
// Build ImageMagick convert command with optimization
$quality = 85; // Balanced quality setting
$cmd = "convert \"$temp_png\" -strip -interlace Plane -gaussian-blur 0.05 -quality $quality ";
$cmd .= "-sampling-factor 4:2:0 \"$generated_image\" 2>&1";
// Build ImageMagick convert command with optimization
$quality = 85; // Balanced quality setting
$cmd = "convert \"$temp_png\" -strip -interlace Plane -gaussian-blur 0.05 -quality $quality ";
$cmd .= "-sampling-factor 4:2:0 \"$generated_image\" 2>&1";
// Execute conversion
$output = [];
$returnVar = 0;
exec($cmd, $output, $returnVar);
// Execute conversion
$output = [];
$returnVar = 0;
exec($cmd, $output, $returnVar);
if ($returnVar === 0 && file_exists($generated_image)) {
// Get file sizes for comparison
$originalSize = filesize($temp_png);
$convertedSize = filesize($generated_image);
if ($returnVar === 0 && file_exists($generated_image)) {
// Get file sizes for comparison
$originalSize = filesize($temp_png);
$convertedSize = filesize($generated_image);
// Clean up temporary PNG file
if (file_exists($temp_png)) {
unlink($temp_png);
}
// Clean up temporary PNG file
if (file_exists($temp_png)) {
unlink($temp_png);
}
// Clean up old generated files
foreach (glob("generated_*.png") as $file) {
if ($file != $generated_image && (time() - filemtime($file)) > 3600) {
unlink($file);
}
}
// Clean up old generated files
foreach (glob("generated_*.png") as $file) {
if ($file != $generated_image && (time() - filemtime($file)) > 3600) {
unlink($file);
}
}
// Store size information for display
$size_info = array(
'original' => round($originalSize / 1024, 2),
'converted' => round($convertedSize / 1024, 2),
'reduction' => round((($originalSize - $convertedSize) / $originalSize) * 100, 2)
);
} else {
// If conversion fails, keep the original PNG
if (file_exists($temp_png)) {
$generated_image = $temp_png;
}
$error_message = "Image conversion failed. Using original PNG format.";
}
}
// Store size information for display
$size_info = array(
'original' => round($originalSize / 1024, 2),
'converted' => round($convertedSize / 1024, 2),
'reduction' => round((($originalSize - $convertedSize) / $originalSize) * 100, 2)
);
} else {
// If conversion fails, keep the original PNG
if (file_exists($temp_png)) {
$generated_image = $temp_png;
}
$error_message = "Image conversion failed. Using original PNG format.";
}
}
}
curl_close($ch);
}
}
} else if ($_SERVER["REQUEST_METHOD"] == "GET" && isset($_GET['load_prompt'])) {
// For loading prompts we use GET method to send the client's choice of prompt to load
// Load saved prompt into textarea
$saved_prompts = loadSavedPrompts();
$prompt = isset($saved_prompts[$_GET['load_prompt']]) ? $saved_prompts[$_GET['load_prompt']] : '';
if (isset($saved_prompts[$_GET['load_prompt']])) {
// Check if the saved prompt is in the new format (array) or old format (string)
if (is_array($saved_prompts[$_GET['load_prompt']])) {
$prompt = $saved_prompts[$_GET['load_prompt']]['prompt'];
$negative_prompt = $saved_prompts[$_GET['load_prompt']]['negative_prompt'];
} else {
// Handle old format
$prompt = $saved_prompts[$_GET['load_prompt']];
$negative_prompt = '';
}
}
}
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
@ -188,10 +207,6 @@ if ($_SERVER["REQUEST_METHOD"] == "POST") {
margin: 10px 0;
border: 1px solid #ddd;
}
.lora-help code {
background-color: #eee;
padding: 2px 4px;
}
.form-group {
margin-bottom: 15px;
}
@ -203,6 +218,15 @@ if ($_SERVER["REQUEST_METHOD"] == "POST") {
font-size: 14px;
border: 1px solid #ddd;
}
textarea#negative_prompt {
width: 100%;
height: 100px;
padding: 8px;
font-family: Arial, sans-serif;
font-size: 14px;
border: 1px solid #ddd;
background-color: #fff3f3;
}
.error-message {
color: #dc3545;
background-color: #f8d7da;
@ -260,7 +284,8 @@ if ($_SERVER["REQUEST_METHOD"] == "POST") {
<select name="load_prompt">
<option value="">Select a saved prompt</option>
<?php foreach ($saved_prompts as $name => $saved_prompt): ?>
<option value="<?php echo htmlspecialchars($name); ?>">
<option value="<?php echo htmlspecialchars($name); ?>"
title="Prompt: <?php echo htmlspecialchars(is_array($saved_prompt) ? $saved_prompt['prompt'] : $saved_prompt); ?>&#13;Negative: <?php echo htmlspecialchars(is_array($saved_prompt) ? $saved_prompt['negative_prompt'] : ''); ?>">
<?php echo htmlspecialchars($name); ?>
</option>
<?php endforeach; ?>
@ -275,6 +300,11 @@ if ($_SERVER["REQUEST_METHOD"] == "POST") {
<textarea name="prompt" id="prompt"><?php echo htmlspecialchars($prompt); ?></textarea>
</div>
<div class="form-group">
<label for="negative_prompt">Enter your negative prompt (things to avoid in the image):</label><br>
<textarea name="negative_prompt" id="negative_prompt"><?php echo htmlspecialchars($negative_prompt); ?></textarea>
</div>
<div class="form-group">
<label for="width">Width:</label>
<input type="number" name="width" id="width" value="<?php echo $width; ?>" min="64" max="2048" step="64">
@ -319,36 +349,38 @@ if ($_SERVER["REQUEST_METHOD"] == "POST") {
<input type="text" name="prompt_name" id="prompt_name" required>
</div>
<input type="hidden" name="prompt" value="<?php echo htmlspecialchars($prompt); ?>">
<input type="hidden" name="negative_prompt" value="<?php echo htmlspecialchars($negative_prompt); ?>">
<input type="submit" name="save_prompt" value="Save Prompt">
</form>
</div>
<?php if (!empty($generated_image)): ?>
<div class="result">
<h2>Generated Image:</h2>
<img width="250px" src="<?php echo htmlspecialchars($generated_image); ?>" alt="Generated image"/>
<br/>
<a download href="<?php echo htmlspecialchars($generated_image); ?>"> Download Generated Image </a>
<?php if (isset($size_info)): ?>
<div class="size-info">
<p>
Original size: <?php echo $size_info['original']; ?> KB<br>
Converted size: <?php echo $size_info['converted']; ?> KB<br>
Size reduction: <?php echo $size_info['reduction']; ?>%
</p>
</div>
<?php endif; ?>
<div class="parameters">
<strong>Parameters used:</strong><br>
Prompt: <?php echo htmlspecialchars($prompt); ?><br>
Processed Prompt: <?php echo htmlspecialchars($processed_prompt); ?><br>
Size: <?php echo $width; ?>x<?php echo $height; ?><br>
Steps: <?php echo $steps; ?><br>
CFG Scale: <?php echo $cfg_scale; ?><br>
Sampler: <?php echo htmlspecialchars($sampler); ?>
</div>
</div>
<?php endif; ?>
<?php if (!empty($generated_image)): ?>
<div class="result">
<h2>Generated Image:</h2>
<img width="250px" src="<?php echo htmlspecialchars($generated_image); ?>" alt="Generated image"/>
<br/>
<a download href="<?php echo htmlspecialchars($generated_image); ?>">Download Generated Image</a>
<?php if (isset($size_info)): ?>
<div class="size-info">
<p>
Original size: <?php echo $size_info['original']; ?> KB<br>
Converted size: <?php echo $size_info['converted']; ?> KB<br>
Size reduction: <?php echo $size_info['reduction']; ?>%
</p>
</div>
<?php endif; ?>
<div class="parameters">
<strong>Parameters used:</strong><br>
Prompt: <?php echo htmlspecialchars($prompt); ?><br>
Negative Prompt: <?php echo htmlspecialchars($negative_prompt); ?><br>
Processed Prompt: <?php echo htmlspecialchars($processed_prompt); ?><br>
Size: <?php echo $width; ?>x<?php echo $height; ?><br>
Steps: <?php echo $steps; ?><br>
CFG Scale: <?php echo $cfg_scale; ?><br>
Sampler: <?php echo htmlspecialchars($sampler); ?>
</div>
</div>
<?php endif; ?>
<?php if (!empty($response)): ?>
<div class="result">
@ -358,4 +390,3 @@ if ($_SERVER["REQUEST_METHOD"] == "POST") {
<?php endif; ?>
</body>
</html>

View file

@ -1,339 +0,0 @@
<?php
ini_set('max_execution_time', '300');
header('Content-Type: text/html; charset=iso-8859-1');
$response = "";
$generated_image = "";
$prompt = "";
$width = 512;
$height = 512;
$steps = 20;
$cfg_scale = 7.5;
$sampler = "Euler";
$error_message = "";
$success_message = "";
$processed_prompt = "";
// File to store saved prompts
$saved_prompts_file = 'saved-prompts.json';
// Load saved prompts
function loadSavedPrompts() {
global $saved_prompts_file;
if (file_exists($saved_prompts_file)) {
$json = file_get_contents($saved_prompts_file);
return json_decode($json, true) ?: array();
}
return array();
}
// Save a new prompt
function savePrompt($prompt_text, $prompt_name) {
global $saved_prompts_file;
$prompts = loadSavedPrompts();
$prompts[$prompt_name] = $prompt_text;
file_put_contents($saved_prompts_file, json_encode($prompts, JSON_PRETTY_PRINT));
}
$saved_prompts = loadSavedPrompts();
// List of available samplers
$samplers = array(
"Euler",
"Euler a",
"Heun",
"DPM2",
"DPM2 a",
"DPM++ 2S a",
"DPM++ 2M",
"DPM++ SDE",
"DPM++ 2M SDE",
"DPM++ 3M SDE",
"DPM fast",
"DPM adaptive",
"LMS",
"DPM++ SDE Karras",
"DPM++ 2M SDE Karras",
"DPM++ 3M SDE Karras",
"DDIM",
"PLMS"
);
if ($_SERVER["REQUEST_METHOD"] == "POST") {
// Handle prompt saving
if (isset($_POST['save_prompt']) && isset($_POST['prompt_name'])) {
$prompt_to_save = trim($_POST['prompt']);
$prompt_name = trim($_POST['prompt_name']);
if (!empty($prompt_to_save) && !empty($prompt_name)) {
savePrompt($prompt_to_save, $prompt_name);
$success_message = "Prompt saved successfully!";
$saved_prompts = loadSavedPrompts(); // Reload prompts
} else {
$error_message = "Both prompt and prompt name are required to save.";
}
}
// Handle image generation
else {
$prompt = isset($_POST['prompt']) ? $_POST['prompt'] : '';
$width = isset($_POST['width']) ? (int)$_POST['width'] : 512;
$height = isset($_POST['height']) ? (int)$_POST['height'] : 512;
$steps = isset($_POST['steps']) ? (int)$_POST['steps'] : 20;
$cfg_scale = isset($_POST['cfg_scale']) ? (float)$_POST['cfg_scale'] : 7.5;
$sampler = isset($_POST['sampler']) ? $_POST['sampler'] : 'Euler';
// Check for angle brackets in the prompt
if (strpos($prompt, '<') !== false || strpos($prompt, '>') !== false) {
$error_message = "Error: Angle brackets are not allowed in the prompt. Please use square brackets [lora-name:weight] for LORAs.";
}
// Only proceed if there's no error
elseif (!empty($prompt)) {
// Process the prompt to handle LORA syntax
$processed_prompt = preg_replace('/\[([\w\s\-]+?):([\d\.]+)\]/', '<lora:$1:$2>', $prompt);
$data = array(
'prompt' => $processed_prompt,
'steps' => $steps,
'width' => $width,
'height' => $height,
'cfg_scale' => $cfg_scale,
'sampler_name' => $sampler,
'override_settings' => new stdClass(),
'override_settings_restore_afterwards' => true
);
// Replace 127.0.0.1 with your Stable diffusion server's IP if running externally
$ch = curl_init('http://127.0.0.1:7860/sdapi/v1/txt2img');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
$result = curl_exec($ch);
if (curl_errno($ch)) {
$response = 'Error: ' . curl_error($ch);
} else {
$decoded = json_decode($result, true);
if (isset($decoded['images'][0])) {
$image_data = base64_decode($decoded['images'][0]);
// Save original PNG temporarily
$temp_png = 'temp_' . time() . '_' . bin2hex(random_bytes(8)) . '.png';
file_put_contents($temp_png, $image_data);
// Create output JPG filename
$generated_image = 'generated_' . time() . '_' . bin2hex(random_bytes(8)) . '.jpg';
// Build ImageMagick convert command with optimization
$quality = 85; // Balanced quality setting
$cmd = "convert \"$temp_png\" -strip -interlace Plane -gaussian-blur 0.05 -quality $quality ";
$cmd .= "-sampling-factor 4:2:0 \"$generated_image\" 2>&1";
// Execute conversion
$output = [];
$returnVar = 0;
exec($cmd, $output, $returnVar);
if ($returnVar === 0 && file_exists($generated_image)) {
// Get file sizes for comparison
$originalSize = filesize($temp_png);
$convertedSize = filesize($generated_image);
// Clean up temporary PNG file
if (file_exists($temp_png)) {
unlink($temp_png);
}
// Clean up old generated files
foreach (glob("generated_*.png") as $file) {
if ($file != $generated_image && (time() - filemtime($file)) > 3600) {
unlink($file);
}
}
// Store size information for display
$size_info = array(
'original' => round($originalSize / 1024, 2),
'converted' => round($convertedSize / 1024, 2),
'reduction' => round((($originalSize - $convertedSize) / $originalSize) * 100, 2)
);
} else {
// If conversion fails, keep the original PNG
if (file_exists($temp_png)) {
$generated_image = $temp_png;
}
$error_message = "Image conversion failed. Using original PNG format.";
}
}
}
curl_close($ch);
}
}
} else if ($_SERVER["REQUEST_METHOD"] == "GET" && isset($_GET['load_prompt'])) {
// Load saved prompt into textarea
$saved_prompts = loadSavedPrompts();
$prompt = isset($saved_prompts[$_GET['load_prompt']]) ? $saved_prompts[$_GET['load_prompt']] : '';
}
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html>
<head>
<title>Stable Diffusion Image Generator</title>
</head>
<body bgcolor="#FFFFFF">
<h1>Stable Diffusion Image Generator</h1>
<?php if (!empty($error_message)): ?>
<table border="1" cellpadding="4" cellspacing="0" width="100%" bgcolor="#FFE4E1">
<tr>
<td><font color="#8B0000"><?php echo htmlspecialchars($error_message); ?></font></td>
</tr>
</table>
<br>
<?php endif; ?>
<?php if (!empty($success_message)): ?>
<table border="1" cellpadding="4" cellspacing="0" width="100%" bgcolor="#E0FFE0">
<tr>
<td><font color="#006400"><?php echo htmlspecialchars($success_message); ?></font></td>
</tr>
</table>
<br>
<?php endif; ?>
<table border="1" cellpadding="4" cellspacing="0" width="100%">
<tr bgcolor="#F0F0F0">
<td>
<h3>How to use LORAs:</h3>
<p>Include LORAs using: [lora-name:weight]<br>
Example: a beautiful landscape by [my-artist-lora:0.8]<br>
Weight values: 0.1 to 1.0<br>
Note: Do not use angle brackets (&lt; &gt;). Use square brackets instead.</p>
</td>
</tr>
</table>
<br>
<table border="1" cellpadding="4" cellspacing="0" width="100%">
<tr>
<td>
<b>Saved Prompts</b><br>
<form method="get" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>">
<select name="load_prompt">
<option value="">Select a saved prompt</option>
<?php foreach ($saved_prompts as $name => $saved_prompt): ?>
<option value="<?php echo htmlspecialchars($name); ?>">
<?php echo htmlspecialchars($name); ?>
</option>
<?php endforeach; ?>
</select>
<input type="submit" value="Load Prompt">
</form>
</td>
</tr>
</table>
<br>
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>">
<table border="0" cellpadding="4" cellspacing="0" width="100%">
<tr>
<td colspan="2"><b>Enter your prompt:</b><br>
<textarea name="prompt" rows="6" cols="60"><?php echo htmlspecialchars($prompt); ?></textarea></td>
</tr>
<tr>
<td><b>Width:</b><br>
<input type="text" name="width" value="<?php echo $width; ?>" size="6"></td>
<td><b>Height:</b><br>
<input type="text" name="height" value="<?php echo $height; ?>" size="6"></td>
</tr>
<tr>
<td><b>Steps:</b><br>
<input type="text" name="steps" value="<?php echo $steps; ?>" size="6"></td>
<td><b>CFG Scale:</b><br>
<input type="text" name="cfg_scale" value="<?php echo $cfg_scale; ?>" size="6"></td>
</tr>
<tr>
<td colspan="2"><b>Sampler:</b><br>
<select name="sampler">
<?php foreach ($samplers as $s): ?>
<option value="<?php echo htmlspecialchars($s); ?>" <?php echo $s === $sampler ? 'selected' : ''; ?>>
<?php echo htmlspecialchars($s); ?>
</option>
<?php endforeach; ?>
</select></td>
</tr>
<tr>
<td colspan="2" align="center">
<input type="submit" value="Generate Image">
</td>
</tr>
</table>
</form>
<br>
<table border="1" cellpadding="4" cellspacing="0" width="100%">
<tr bgcolor="#F0F0F0">
<td>
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>">
<b>Save Current Prompt</b><br>
Prompt Name: <input type="text" name="prompt_name" size="30"><br>
<input type="hidden" name="prompt" value="<?php echo htmlspecialchars($prompt); ?>">
<input type="submit" name="save_prompt" value="Save Prompt">
</form>
</td>
</tr>
</table>
<?php if (!empty($generated_image)): ?>
<br>
<table border="1" cellpadding="4" cellspacing="0" width="100%">
<tr>
<td>
<h2>Generated Image:</h2>
<img width="250" src="<?php echo htmlspecialchars($generated_image); ?>" alt="Generated image">
<br>
<a href="<?php echo htmlspecialchars($generated_image); ?>">Download Generated Image</a>
<?php if (isset($size_info)): ?>
<p>
Original size: <?php echo $size_info['original']; ?> KB<br>
Converted size: <?php echo $size_info['converted']; ?> KB<br>
Size reduction: <?php echo $size_info['reduction']; ?>%
</p>
<?php endif; ?>
<p><b>Parameters used:</b><br>
Prompt: <?php echo htmlspecialchars($prompt); ?><br>
<?php if (!empty($processed_prompt)): ?>
Processed Prompt: <?php echo htmlspecialchars($processed_prompt); ?><br>
<?php endif; ?>
Size: <?php echo $width; ?>x<?php echo $height; ?><br>
Steps: <?php echo $steps; ?><br>
CFG Scale: <?php echo $cfg_scale; ?><br>
Sampler: <?php echo htmlspecialchars($sampler); ?></p>
</td>
</tr>
</table>
<?php endif; ?>
<?php if (!empty($response)): ?>
<br>
<table border="1" cellpadding="4" cellspacing="0" width="100%">
<tr>
<td>
<h2>Error:</h2>
<p><?php echo htmlspecialchars($response); ?></p>
</td>
</tr>
</table>
<?php endif; ?>
</body>
</html>