OpenAI DALL-E Base64 Image Generation with HTML, PHP, cURL, and Javascript AJAX

|

This is a barebones example using OpenAI’s DALL-E Base64 image generation with PHP from a user prompt on a web page.

Image generation is in beta as of this writing.

Cat riding motorcycle over neural net diagram

The drawing of the cat riding on the motorcycle was generated using the code in this article. Then using an image editor the cat motorcycle image was pasted over a neural network illustration from free stock imagery and then over a black background.

I wanted to write a PHP program that would use the DALL·E API from OpenAI to generate images. DALL-E is an AI system that can create realistic images and art from a description in natural language. Like ChatGPT there is an user interface at a charge to access DALL-E. You can also write code to access it. Visit the OpenAI DALL-E web page to learn more about it and access the user interface.

“In January 2021, OpenAI introduced DALL·E. One year later, our newest system, DALL·E 2, generates more realistic and accurate images with 4x greater resolution.” – OpenAI

– OpenAI

This example requests base64 data from the DALL-E API. You can also request an image URL. The code for a URL is slightly different and you can check that out at OpenAI DALL-E Image URL Generation with HTML, PHP, cURL, and Javascript AJAX.

ChatGPT GPT-4 was used to assist in the code writing. Because its knowledge cutoff date of September 2021 it used some parameter values that were changed since. It also included parameters that are no longer needed for the same reason. Solutions to all were easily remedied using debugging tools and documentation.

You do need an account and an API key from the OpenAI Platform. If you are using ChatGPT then you have an account.

I kept the user interface style simple but gets the job done for a learning example.

Web user interface for the example to fetch BASE64 image from the DALL-E image API
User Interface Screenshot

To keep coding simple I loaded the API key using a hidden file. There is only one line in the file and it contains the API key. My file name is .open-php-curl-env. You can use any file name. Here is my code for that.

PHP – Loading OpenAI API Key
		// Load the OpenAI API key
		// Create a text file (name optional) with your OpenAI API Key on the first line. 
		$api_key = file_get_contents('.openai-php-curl-env');

You need credits with OpenAI in addition to the API key. Recently new accounts have a free grant of credits.

PHP uses the cURL library to communicate with OpenAI’s API. The API endpoint is https://api.openai.com/v1/images/generations. There are various options to include in the request body. I put them into an array for use in cURL.

PHP – OpenAI image/generations endpoint Request Body data
		$data = array(
			"prompt" => $_POST['prompt'],
			"size" => '512x512', //256x256, 512x512, or 1024x1024 pixels
 			"n" => 1, // Number of images
			"response_format" => "b64_json", //url | b64_json. URLs will expire after an hour.
		);

The prompt is the user request text coming from the web page. There are four image sizes. Smaller sizes have faster response times and perhaps they use less credits.

More than one image variation can be requested at a time using the n value. The images are returned in an array. The request value is set to one since the example code is written to only use one image.

There are two response format values. The url value returns a URL that expires after 1 hour. The b64_json value returns image data. In either case you can copy or save the image from the web page. The url value can be used with modifications to this code and you can check those in this complete example I posted at OpenAI DALL-E Image URL Generation with HTML, PHP, cURL, and Javascript AJAX

The cURL code is template ready to plug in the values.The OpenAI API request endpoint is in line 25. Line 28 is where data is converted to JSON format for the request body. Line 31 has the api key in the $api_key variable.

The request occurs on line 33. If the cURL fails, the error is dumped to the error log on line 35. The error logging line can be removed unless you are testing and debugging.

PHP – cURL
		// cURL processing
		$ch = curl_init();
		curl_setopt($ch, CURLOPT_URL, 'https://api.openai.com/v1/images/generations');
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
		curl_setopt($ch, CURLOPT_POST, 1);
		curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
		$headers = array();
		$headers[] = 'Content-Type: application/json';
		$headers[] = 'Authorization: Bearer ' . $api_key;
		curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
		$response_raw = curl_exec($ch);
		if (curl_errno($ch)) {
			error_log('error: ' . curl_error($ch));

If the OpenAI API request succeeded, then the image’s base 64 data can be extracted from the response’s data array. The response is in the JSON format so it needs to be decoded for use in PHP. That is done on line 39. The lack of the error key in the response signifies that OpenAI’s API succeeded. We are doing nothing if there is an error key but simply log the response. You can uncomment line line 37 if there are issues with the response value.

Line 42 is where the image base64 data is extracted from the response’s data array. The request was for one image line 20 so the 0 index contains the base64 data. This is found in each data array item as the b64_json key.

For more than one image, then you need to modify to loop though the data array and return each image to the front end. The HTML and Javascript code needs to changed appropriately to handle multiple images.

PHP – Extracting the URL and update AJAX return data.
		}else{
			//error_log('$response_raw: ' . print_r($response_raw,true));
			// Decode the JSON response
			$jsonResponse = json_decode($response_raw, true);
			if (!isset($jsonResponse['error'])) {
				// The image
				$base64Image = $jsonResponse['data'][0]['b64_json'];
				// The image in the response
				$rtn_val['image'] = $base64Image;
				$rtn_val['success'] = true;
			}

The $rtn_val variable is my coding choice for packaging the data to return to the front-end. I use a success key and it is defaulted to false at the start of the file on line 4 and only set to true once all the processing has completed successfully. The $rtn_val variable’s image key is just a programmer’s choice for tagging the return data for front end consumption.

I am using the JSON format for AJAX, so the $rtn_val is converted to JSON format and for the response sent to the waiting front end.

PHP – Return the request in JSON format
//Respond with JSON content
header('Content-Type: application/json');
echo json_encode( $rtn_val );

How to handle AJAX requests and responses is a programmer’s choice. It is important to validate and sanitized data received from the front-end. Minimal validation was added on lines 6 to 12. No sanitation is included. Since the front end data is sent untouched to the OpenAI API, it is assumed sanitation will occur there.

The Javascript file uses jQuery to handle the AJAX lines 18 – 46. Line 32 tests for the success key in the response data. If its true then on line 33 positive user feedback shown in the results element. The image base64 data is set to the img element’s src element on line 35. If the success key is false, negative user feedback is added on line 37.

JS – AJAX handling
	function sendPromptAjax(){
		$('#results').html('...processing...');
		let dataSend = {};
		dataSend['prompt'] = $('#prompt').val();
		$.ajax(
			{
				type:"post",
				url:"openai-image-02.php",
				data:dataSend,
				dataType:'json',
			}
		)
		.done(
			function(data, status){
				if (data.success){
					console.log("sendPromptAjax | Success true");
					$('#results').html('Success');
					$("#open-ai-image").attr("src", "data:image/png;base64," + data.image);
				}else{
					$('#results').html('Request failed.');
				}
			}
		)

The key HTML elements are on lines 23-26 of the HTML file. jQuery listens to click events for the button element on line 24 and sends the input element value on line 23 to the backend.

Processing, positive and negative message are shown in the results element on line 26 and are updated by jQuery.

The image element’s src attribute on line 25 is set to the base64 data by jQuery.

HTML – Relevant elements for interaction
	<div><p class="text-align-left"><input id="prompt" type="text" placeholder="Enter a prompt" ><br>Ex: A white siamese cat.<br>A beautiful sunset over the mountains</p></div>
	<div><p><button id="send">Send</button></p></div>
	<div><image id="open-ai-image"/></div>
	<div><p id="results"></p></div>

There are 5 files in total.

  • .openai-php-curl-env
  • openai-image-02.html
  • openai-image-02.css
  • openai-image-02.js
  • openai-image-02.php
Posted on April 21st, 2023 | Updated on April 22nd, 2023