After a request the other day from @Daller, I threw together a quick and simple solution with just two PHP files—one for the backend, one for the form—and some vanilla JavaScript (no libraries, just good old AJAX and cURL). Kept it basic to make things easy for those new to DALLE API.
The images are pulled from a URL that DALL·E 3 gives you, but they won’t last forever, so you’ll want to download them if you want to hang onto them. Or, if you’re feeling adventurous, you can modify the code to save the images locally (that’s your homework!).
index.php (frontend)
<?php
session_start();
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Generate Image with DALL·E 3</title>
<style>
body { font-family: Arial, sans-serif; margin: 20px; }
textarea { width: 100%; height: 100px; padding: 10px; font-size: 16px; margin-bottom: 20px; border: 1px solid #ccc; border-radius: 5px; }
select { width: 100%; padding: 10px; font-size: 16px; margin-bottom: 20px; border: 1px solid #ccc; border-radius: 5px; }
button { padding: 10px 20px; font-size: 16px; cursor: pointer; background-color: #007bff; color: white; border: none; border-radius: 5px; }
button:disabled { background-color: #999; cursor: not-allowed; }
.error { color: red; margin-top: 20px; }
.image { display: inline-block; margin: 10px; }
.image img { max-width: 100%; height: auto; }
#main-image { margin-top: 20px; }
#history-images { margin-top: 20px; }
#spinner { display: none; margin-top: 20px; }
</style>
</head>
<body>
<h1>Generate Image with DALL·E 3</h1>
<form id="imageForm">
<label for="prompt">Enter a text prompt:</label><br><br>
<textarea id="prompt" name="prompt" placeholder="Enter your prompt here..."></textarea>
<br>
<!-- Add image size options -->
<label for="size">Select Image Size:</label><br><br>
<select id="size" name="size">
<option value="1024x1024">1024x1024</option>
<option value="1792x1024">1792x1024 (Wide)</option>
<option value="1024x1792">1024x1792 (Tall)</option>
</select>
<br>
<button type="submit">Generate Image</button>
</form>
<div id="spinner">
<p>Generating image... Please wait.</p>
</div>
<div id="error" class="error"></div>
<div id="main-image"></div> <!-- Main image display area -->
<h2>History</h2>
<div id="history-images"></div> <!-- History of generated images -->
<script>
document.getElementById('imageForm').addEventListener('submit', function(e) {
e.preventDefault(); // Prevent default form submission
const prompt = document.getElementById('prompt').value.trim();
const size = document.getElementById('size').value;
if (!prompt) {
document.getElementById('error').innerText = 'Please enter a valid prompt.';
return;
}
document.getElementById('error').innerText = ''; // Clear previous errors
document.getElementById('spinner').style.display = 'block'; // Show spinner
document.querySelector('button').disabled = true; // Disable button
// Create new AJAX request
let xhr = new XMLHttpRequest();
xhr.open('POST', 'genimage.php', true); // Keep pointing to genimage.php
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
// Handle response
xhr.onload = function() {
document.getElementById('spinner').style.display = 'none'; // Hide spinner
document.querySelector('button').disabled = false; // Re-enable button
if (xhr.status === 200) {
try {
let response = JSON.parse(xhr.responseText);
if (response.error) {
document.getElementById('error').innerText = response.error;
} else if (response.url) {
// Show the newly generated image
let mainImageDiv = document.getElementById('main-image');
mainImageDiv.innerHTML = ''; // Clear current main image
let img = document.createElement('img');
img.src = response.url;
img.alt = 'Generated Image';
mainImageDiv.appendChild(img);
// Update the session history with the new image
let historyDiv = document.getElementById('history-images');
let historyImageDiv = document.createElement('div');
historyImageDiv.className = 'image';
let historyImg = document.createElement('img');
historyImg.src = response.url;
historyImg.alt = 'Generated Image';
historyImageDiv.appendChild(historyImg);
historyDiv.appendChild(historyImageDiv); // Add to the history section
}
} catch (e) {
document.getElementById('error').innerText = 'Error parsing response: ' + e.message;
}
} else {
document.getElementById('error').innerText = 'Server error occurred. Status: ' + xhr.status;
}
};
// Handle request errors
xhr.onerror = function() {
document.getElementById('spinner').style.display = 'none'; // Hide spinner
document.querySelector('button').disabled = false; // Re-enable button
document.getElementById('error').innerText = 'Request failed. Network or server error.';
};
// Send request with prompt and selected size
xhr.send('prompt=' + encodeURIComponent(prompt) + '&size=' + encodeURIComponent(size));
});
</script>
</body>
</html>
…and…
genimage.php (backend)
<?php
session_start();
// Replace with your OpenAI API key
$api_key = 'API-KEY-HERE'; // Use your actual API key here
// Check if prompt and size are provided
if (isset($_POST['prompt']) && isset($_POST['size'])) {
$prompt = htmlspecialchars(trim($_POST['prompt']));
$size = htmlspecialchars(trim($_POST['size']));
if (!empty($prompt) && !empty($size)) {
// Initialize cURL session
$ch = curl_init();
// Payload for the API request
$payload = json_encode([
"prompt" => $prompt,
"n" => 1,
"model" => "dall-e-3",
"size" => $size,
"response_format" => "url",
"user" => session_id() // Use session ID as user identifier
]);
// Set cURL options
curl_setopt($ch, CURLOPT_URL, "https://api.openai.com/v1/images/generations");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Content-Type: application/json",
"Authorization: Bearer $api_key"
]);
// Execute the cURL request
$response = curl_exec($ch);
$http_status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($http_status == 200) {
$data = json_decode($response, true);
if (isset($data['data'][0]['url'])) {
$image_url = $data['data'][0]['url'];
// Store the generated image in the session history
if (!isset($_SESSION['history'])) {
$_SESSION['history'] = [];
}
$_SESSION['history'][] = ['prompt' => $prompt, 'images' => [$image_url]];
// Return the image URL as JSON
echo json_encode(['url' => $image_url]);
} else {
echo json_encode(['error' => 'Failed to generate image.']);
}
} else {
// Handle API or cURL errors
$data = json_decode($response, true);
$error_message = isset($data['error']['message']) ? $data['error']['message'] : 'Unknown error occurred.';
echo json_encode(['error' => $error_message]);
}
} else {
echo json_encode(['error' => 'Invalid prompt or size.']);
}
} else {
echo json_encode(['error' => 'No prompt or size provided.']);
}
I’ve tested it on a server, and it’s clunky, but it works! Some limitations compared to ChatGPT DALLE generation (you can’t say, change this or that in the last image), but if you’ve ever wanted to tinker with DALLE API, here’s your chance.
If anyone does make improvements, feel free to share them here to help others out!