Build Your Own AI Image Creation Application

I don’t paint dreams or nightmares. I paint my own reality

Frida Kahlo

Welcome back to my “Build Your Own” series of blog articles. In previous posts, I discussed two ways to build your own ChatGPT lookalike application. This time around, I want to show you how you can use an OpenAI API and the DALL-E3 Large Language Model to create AI generated images. With this application, you simply describe what you want to see (e.g. “Santa Claus sitting on a beach with a tropical drink in his hand”) and voila, it’s yours!

Before I give you the source code for the application, take a look at this Cheapo-Cheapo Productions video where I show you how it works.

The source code for this application is contained in two modules. For ease of explanation, I put the HTML and JavaScript into one file (index.html) and the CSS into another (openai.css). To use the application, you need to replace the OPENAI_AUTH value with your own OpenAI developer key.

<!DOCTYPE html>

<html>
<head>
<title>Andrew's DALL-E3 Image Generator</title>
<link rel="stylesheet" href="css/openai.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js" integrity="sha512-v2CJ7UaYy4JwqLDIrZUI/4hqeoQieOmAZNXBeQyjo21dadnwR+8ZaIJVT8EE2iyI61OV8e6M8PP2/4hpQINQ/g==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
</head>
<body>
<div class="container">
<div class="container-fluid">
<br>
<div class="col-sm-12 ">
<div style="width: 100%" class="form-group mb-3">
<textarea placeholder="Image description" class="form-control" id="imageDescription" rows="2"></textarea>
</div>
<button style="padding: 0.8rem 8rem" id="createImage" class="btn btn-primary " onclick="createImage()" >Create Image</button>
</div>
<br>
<div class="col-sm-12">
<div id="console-log" class="console-div" readonly=""></div>
</div>
</div>
</div>
<script type="text/javascript">
const IMAGE_URL = "https://api.openai.com/v1/images/generations";
const OPENAI_AUTH = "xxxxxxxxx";
const MODEL = "dall-e-3";

$(document).ready(init);

function init() {
var input = document.getElementById("imageDescription");
input.addEventListener("keyup", function(event) {
if (event.key === "Enter") {
event.preventDefault();
document.getElementById("createImage").click();
}
});
}

function clearAllChats() {
var consoleTxt = $('#console-log').val();
$('#console-log').val("");
$("#console-log span").remove();
}

async function callGPT(description) {
$('#createImage').prop("disabled", true);
$("body").css("cursor", "progress");
const openAI = {
"model": MODEL,
"prompt": description,
"n": 1,
"size": "1024x1024",
"style": "vivid" // vivid or natural
};

await $.ajax({
type: "POST",
url: IMAGE_URL,
data: JSON.stringify(openAI),
headers: {"Authorization": `Bearer ${OPENAI_AUTH}`, "Content-Type": "application/json", "Accept": "application/json"},
success: function(msg){
addToConsole(`DALL-E3 Description: ${msg.data[0].revised_prompt}`, "Agent");
addImageToConsole(`${msg.data[0].url}`)
$("body").css("cursor", "default");
$('#createImage').prop("disabled", false);
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
$("body").css("cursor", "default");
alert("Invalid image request");
$('#createImage').prop("disabled", false);
}
});
}

async function createImage() {
var input = document.getElementById("imageDescription").value;
if(input.trim() == '') {
alert("Image description required.")
} else {
response = await callGPT(document.getElementById('imageDescription').value);
document.getElementById("imageDescription").value = "";
}
}

function addImageToConsole(url) {
var span = createImageElement(url);
$('#console-log').append(span);
document.getElementById("console-log").scrollTop = document.getElementById("console-log").scrollHeight;
}

function createImageElement(url) {
var span = document.createElement('span');
$(span).addClass('log-element-agent');
var sendSpan = document.createElement('span');
$(sendSpan).addClass('log-element-sender');
sendSpan.innerHTML = `<img src="${url}" alt="" width="950" height="950">`;
var msgSpan = document.createElement('span');
$(msgSpan).addClass('log-element-msg');
$(span).append(sendSpan);
$(span).append(msgSpan);
return span;
}

function writeToTrace(text, requestor) {
text = text.trim();
addToConsole(text, requestor);
}

function addToConsole(msg, requestor) {
var span = createLogElement(msg, requestor);
$('#console-log').append(span);
document.getElementById("console-log").scrollTop = document.getElementById("console-log").scrollHeight;
}

function createLogElement(msg, type) {
var span = document.createElement('span');
if (type == "User") {
$(span).addClass('log-element');
} else {
$(span).addClass('log-element-agent');
}
var msgArray = msg.split(':');
var sender = msgArray[0];
var restMsg = "";
for (var i = 1; i < msgArray.length; i++) {
if (i == 1) {
restMsg += " " + msgArray[i];
} else {
restMsg += ":" + msgArray[i];
}
}
var sendSpan = document.createElement('span');
$(sendSpan).addClass('log-element-sender');
sendSpan.innerHTML = sender + ":";
var msgSpan = document.createElement('span');
$(msgSpan).addClass('log-element-msg');
restMsg = restMsg.replaceAll(`\n`, `<BR>`)
$(msgSpan).append(messageWithLink(restMsg));
$(span).append(sendSpan);
$(span).append(msgSpan);
return span;
}

function messageWithLink(msg) {
var matches = msg.match(/[(http(s)?):\/\/(www\.)?a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/g);
if (matches) {
for (var i = 0; i < matches.length; i++) {
if (matches[i].toLowerCase().indexOf("http") != -1) {
// The user or agent put a link into the chat window
msg = msg.replace(matches[i], ' <a href = "' + matches[i] + '"target = "_blank" > ' + matches[i] + ' </a>');
}
}
}
return msg;
}
</script>
</body>
</html>

Here is the CSS.

.log-element {

display: block;
margin-top: 5px;
margin-bottom: 5px;
margin-left: 1%;
margin-right: 1%;
background: #fce4c5;
border-radius: 5px;
padding: 10px;
font-family: "Noto Sans JP", sans-serif;
font-size: 13px;
max-width: 1024px;
box-sizing: content-box;
}

.log-element-agent {
display: block;
margin-top: 5px;
margin-bottom: 5px;
margin-left: 1%;
margin-right: 1%;
background: #43c2dc;
border-radius: 5px;
padding: 10px;
font-family: "Noto Sans JP", sans-serif;
font-size: 13px;
max-width: 1024px;
box-sizing: content-box;
}

.log-element-sender {
font-weight: bold;
font-style: italic;
font-size: 13px;
font-family: "Noto Sans JP", sans-serif;
}

.log-element-msg {
word-wrap: break-word;
}

#console-log {
background-color: white;
padding: 2%;
width: 100%;
overflow-y: scroll;
min-height: 100px;
}

.console-div{
display:block;
width:100%;
height:850px;
background-color:#475;
overflow:scroll;
}

To use the application, download index.html into a directory on your PC. Create a new directory in that directory and call it css. Download openai.css into the css directory. Add your OPENAI_AUTH key into index.hml. You can now double click on index.html and start creating your own AI images. It’s that simple.

Mischief Managed

I would be thrilled if folks took my code and started playing with. I would be especially happy if people improved on my weak user interface and shared the code with the readers of this blog and me. We all do better when we all do better. 

Happy programming!

4 comments

  1. Abhishek Jyothishbabu · · Reply

    HI Andrew,

    Thanks a lot for the wonderful blog, as always.

    I have bit of free time these days and I can tweak the UI.

    Let me know if you have any specific thoughts on UI layout and also if you prefer to have it using plain HTML or we can use some frameworks like bootstrap or angular.

    1. I would love to see what you come up with. Bootstrap would be a good start. I’m not ready for Angular yet. 🙂

      1. Abhishek jyothish · ·

        Sure, will share a sample UI with you soon. 🙂

  2. Abhishek Jyothishbabu · · Reply

    Ohh My bad. Just noticed that you are already using bootstrap. 😅

Leave a comment