In this article we will build a web app that generates images using Open AI API with PHP. This app will take user prompts as an input to generate images based on the prompts. Users can describe what to generate in the image and this AI will generate the images based on the users imagination. So follow below step by step guide to build your very first AI powered image generator using PHP.
1: Get OpenAi’s token
Head over to OpenAI(https://platform.openai.com/) or openai.com to create a new account you need to a signup page like this
After you successfully sign up it will redirect to you to the a dashboard(https://platform.openai.com/) and it should look like this
Now click on your profile image or name and in the drop down menu click on view API keys and from there you need to create a new project to generate the API key so click on Create new secret key and write a name for it and the it will display you the API key MAKE SURE TO COPY THE API KEY before you close the popup box, because you can’t copy the key again.
Now you are good to go, Remember to always keep your API key secure and avoid sharing it publicly
2: Set The Basic HTML Template
First thing you need to do is create a folder for this app you can name it whatever you liked or name “ai-image-generator” now inside this create two more folders 1:backend for php files, 2:frontend for css,images.js files and also create another folder name it uploads in frontend folder for generated images
now your directory structure would look like this
ai-image-generator/
├── backend/
│ └── classes/
│
├── frontend/
│ ├── css/
│ ├── images/
│ ├── js/
│ └── uploads/
│
└── index.php
Now download the basic html template from HERE, of course you can use any html template you like or create your own template. extract the files somewhere and copy all the html from index.html and create a new index.php file in your app folder and place that html code. And also copy all other folders from that template and paste into your frontend folder
Now open your browser to access your web app page, if you see the app page like below you are good to go.
3: Validate The Main page
In our template we have the text input field for user prompt named prompt and and the submit button named generate. Now before starting html tag add this php code block
<?php
//Include the config file from backend folder to call other classes
include 'backend/config.php';
//Variable to store generated image from the AI
$image = "";
//check the post request method, make sure it's a post request
if($_SERVER['REQUEST_METHOD'] === "POST"){
//check if generate button pressed
if(isset($_POST['generate'])){
//variable to store users prompt to generate image
$prompt = $_POST['prompt'];
//check if provided prompt is not empty
if(!empty($prompt)){
//remove white spaces from the string
$prompt = trim($prompt);
//set the prompt the ImageGenerator class property
$genObj->prompt = $prompt;
//call the generate method from the class to generate the image
$image = $genObj->generate();
}else{
//if user prompt is empty display error
$error = "Field are requried!.";
}
}
}
?>
So this code block first checks the post request method using the php $_SERVER which is a PHP super global variable used to get information about the HTTP header and other info.
After that we check if our submit button is pressed using $_POST['generate'] and then we created a $prompt variable to get user prompt from the prompt text field using the $_POST[‘prompt’]
and after that we check if our prompt variable is not empty using the empty function if the prompt field is not empty then remove the white spaces from the user prompt using the trim function or else set an error variable to display error
And then set the prompt property in the ImageGenrator class to use in our API call, we’ll explain this in the below step. And finally we call our generate method which we will create to generate the image.
4:Create Our PHP Class to Handle the API Request
First thing you need to is create a new file in the backend folder, named config.php in this file we will include our Image Generator class that we will create in this step.
this will be our config.php
<?php
//Include classes
require 'classes/ImageGenerator.php';
//instantiate the class
$genObj = new ImageGenerator;
//Create API_TOKEN constant to get acces to api key
define('API_TOKEN', 'your-api-key-here');
?>
now you need to create a new php file in the classes folder it will be our php class so name it ImageGenerator.php
And this will be our ImageGenerator class
<?php
class ImageGenerator{
//Properties
//Store errors
public $error;
//Store User Prompt to generate the image
public $prompt;
//Store Api header to add api token to the api call
public $headers;
//This data will be attech to the api call to send the prompt
public $data;
//function to display errors
public function errors(){
return $this->error;
}
//function to set the api header to attech the API token
public function setApiHeader(){
$this->headers =
[
'Authorization: Bearer ' . API_TOKEN,
'Content-Type: application/json'
];
}
//function to set the prompt to the data property
public function setApiData(){
$this->data =
[
'prompt' => $this->prompt
];
}
//function to generate the image
public function generate(){
//set the api url for dall-e to generate the images
$apiUrl = "https://api.openai.com/v1/images/generations";
//call the function to set the header for api call
$this->setApiHeader();
//call the function to set the data to send
$this->setApiData();
//initializes a new cURL session.
$ch = curl_init($apiUrl);
//set options for cURL session to allow to post data
curl_setopt($ch, CURLOPT_POST, true);
//set the data to send via api call
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($this->data));
//set the header(the token key)
curl_setopt($ch, CURLOPT_HTTPHEADER, $this->headers);
//set option to return the data
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
//send the request
$response = curl_exec($ch);
//close the cURL session
curl_close($ch);
//check if response return the api call
if($response){
//decode the json response returned from the api call
$responseData = json_decode($response, true);
//now call the method to save the images to app
$file = $this->saveImage($responseData['data'][0]['url']);
//return file to use
return $file;
}else{
//else set error to display
$this->error = "API Request failed!";
return false;
}
}
//function to save the AI generated image to directory
public function saveImage($response){
//create variable to store image returned from the api call
$imageUrl = $response;
//set folder to save the image
$uploadDir = 'frontend/uploads/';
//Generate filename
$filename = $uploadDir.md5(time()).'_.png';
//create the image using the image
file_put_contents($filename, file_get_contents($imageUrl));
//return the image to display in main page
return $filename;
}
}
Explanation:
First we start off with the config.php file we created in the backend folder, in this file we actually include ImageGenerator class we created in the classes folder then we created the $genObj object to we can acces the class methods and properties.
After the we define the API_TOKEN constant to acess the openAi's api key just by call this constant in any where in our app.
And in our ImageGenerator class we created five different methods
- errors() to display errors
- setApiHeader() to attech the api token using the API_TOKEN constant.
- setApiData() to set the prompt in data property to attech in API call
- generate() to generate the Images
- saveImage() to save the image return from the api call
So for errors method we simply return the error property which will be the error to display in our app. and for setApiHeader method we created an array to store the api token key to send to api
and for setApiData we created an array to store the prompt to send it to api, you can aslo add more options to the data to tell AI about the image.
and for generate method we start of with setting the api url to use the dall-e model to use, and then we call our methods to set headrs for api key and api data to set prompt data
After that we use cURL to send the http request to api with data and cURL return the api data back so we decode the json data because the api returns the json data.
and then we call our saveImage method to store the image we get form the AI. And in ths saveImage method we first created the $imageUrl variable to store image from API and the created $uploadDir to set directory to store images in.
Then we generated the image name using md5 function and current time then we use file_put_contents and file_get_contents to save the image
and finally return the image to display in a page.
And to display the generated image from the method or display the errors update the index.php file with this codes
index.php
<?php
//Include the config file from backend folder to call other classes
include 'backend/config.php';
//Variable to store generated image from the AI
$image = "";
//check the post request method, make sure it's a post request
if($_SERVER['REQUEST_METHOD'] === "POST"){
//check if generate button pressed
if(isset($_POST['generate'])){
//variable to store users prompt to generate image
$prompt = $_POST['prompt'];
//check if provided prompt is not empty
if(!empty($prompt)){
//remove white spaces from the string
$prompt = trim($prompt);
//set the prompt the ImageGenerator class property
$genObj->prompt = $prompt;
//call the generate method from the class to generate the image
$image = $genObj->generate();
}else{
//if user prompt is empty display error
$error = "Field are requried!.";
}
}
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>MyAI</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link href="https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" integrity="sha512-1ycn6IcaQQ40/MKBW2W4Rhis/DbILU74C1vSrLJxCq57o941Ym01SwNsOMqvEBFlcgUa6xLiPY/NS5R+E6ztJQ==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<link rel="stylesheet" type="text/css" href="frontend/css/style.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@100;300;400;500;700&display=swap" rel="stylesheet">
<script src="https://code.jquery.com/jquery-3.7.0.slim.min.js" integrity="sha256-tG5mcZUtJsZvyKAxYLVXrmjKBVLd6VpVccqz/r4ypFE=" crossorigin="anonymous"></script>
<link rel="apple-touch-icon" sizes="180x180" href="frontend/images/favicon/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="frontend/images/favicon/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="frontend/images/favicon/favicon-16x16.png">
<link rel="manifest" href="frontend/images/favicon/site.webmanifest">
<link rel="mask-icon" href="frontend/images/favicon/safari-pinned-tab.svg" color="#5bbad5">
<meta name="msapplication-TileColor" content="#da532c">
<meta name="theme-color" content="#ffffff">
</head>
<body>
<form id="form" method="POST">
<div class="wrapper flex flex-1">
<div class="inner-wrapper flex flex-1 w-full h-screen">
<!--CONTENT_WRAPPER-->
<div class="flex flex-1 h-full items-start justify-center">
<!--INNER_CONTENT_WRAPPER-->
<div class="flex flex-1 w-full flex-col items-center justify-center">
<!--LOGO_SECTION-->
<div class="w-full flex flex-1 items-center justify-center flex-col">
<!--LOGO_IMAGE_DIV-->
<div class="w-96 overflow-hidden items-center sm:mt-0 md:mt-20 sm:mt-20 mb-6 flex justify-center flex-col text-center">
<div id="loader" class="hidden w-40 h-40 overflow-hidden">
<img src="frontend/images/loding.gif">
</div>
<!-- Check if Image is generated -->
<?php if(!empty($image)):?>
<img src="<?php echo $image;?>"/>
<span class="text-gray-800 text-sm">Image successfuly generated</span>
<?php else:?>
<!-- else display the logo image -->
<img id="logo" src="frontend/images/mygpt.png"/>
<span class="text-red-800 text-sm font-bold">
<?php
if(isset($error)){
echo $error;
}
?>
</span>
<?php endif;?>
</div>
<!--LOGO_IMAGE_DIV_ENDS-->
<!--INPUT_SECTION-->
<div class="2xl:w-1/3 md:w-2/3 sm:w-3/4 w-10/12">
<label class="relative">
<span class="absolute flex left-4 text-gray-300" style="top:3px;"><i class="fas fa-search"></i></span>
<input class="pl-9 py-3 pr-3 border w-full text-gray-800" type="text" name="prompt" placeholder="Generate images by AI" />
</label>
</div>
<!--INPUT_SECTION_ENDS-->
</div><!--LOGO_SECTION_END-->
<!--BOTTOM_SECTION-->
<div>
<!--BOTTON_WRAPPER-->
<div class="pt-5 flex items-center justify-center flex-col">
<div>
<button class="bg-green-500 px-3 py-1 rounded text-white hover:shadow-md" name="generate">Generate Image</button>
</div>
</div>
<!--BOTTON_WRAPPER_ENDS-->
</div>
<!--BOTTOM_SECTION_ENDS-->
</div>
<!--INNER_CONTENT_WRAPPER_ENDS-->
</div>
<!--CONTENT_WRAPPER_ENDS-->
</div>
</div>
</form>
<script>
//check if form is submit
$("#form").submit(function() {
//hide logo image
$("#logo").hide();
//display the loading image
$("#loader").removeClass('hidden');
});
</script>
</body>
</html>
At bottom of this index.php file we used a Jquery function to check if the form is submitted then hide the logo and display the loading gif image.
Download Full Source Codes HERE
Thank you for the example you gave. I wonder how we specify the image size when creating an image.
ReplyDeleteThanks
Hi there, Yes you can do that, by providing an image size to the data array, in the setApiData function, add this 'size': '1024x1024' below 'prompt' => $this->prompt
Delete