To start the text to image API first you need to head over to RapidAPI, login and subscribe to the Dezgo API for $2 a month which gives you 20,000 credits a month. Under the current API settings each image is about 19 credits however the code below upscales the image by 2 so this comes in at about 35 credits per image. Setting the upscale to 2 doubles the size of the returned image (512x512 to 1024x1024).
Before we start with the code, lets create the database table for the images to be stored and another table that will store the model/styles the user can select before generating the image.
Make id Auto Increment
CREATE TABLE `text2img` (
`id` int(11) NOT NULL,
`data_json` json NOT NULL,
`description` longtext NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Make id Auto Increment
CREATE TABLE `txt2img_styles` (
`id` int(3) NOT NULL,
`op_value` varchar(30) NOT NULL,
`display` varchar(30) NOT NULL,
`img` varchar(100) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Insert styles/models into database
INSERT INTO `txt2img_styles` (`id`, `op_value`, `display`, `img`) VALUES
(1, 'abyss_orange_mix_2', 'Abyss Orange Mix 2', 'https://static.dezgo.com/samples/models2/d/o/abyss_orange_mix_2.jpg'),
(2, 'analog_diffusion', 'Analog Diffusion', 'https://static.dezgo.com/samples/models2/d/o/analog_diffusion.jpg'),
(3, 'deliberate', 'Deliberate', 'https://static.dezgo.com/samples/models2/d/o/deliberate.jpg'),
(4, 'future_diffusion', 'Future Diffusion', 'https://static.dezgo.com/samples/models2/d/o/future_diffusion.jpg'),
(5, 'openjourney', 'Open Journey', 'https://static.dezgo.com/samples/models2/d/o/openjourney.jpg'),
(6, 'openniji', 'Open niji (Anime)', 'https://static.dezgo.com/samples/models2/d/o/openniji.jpg'),
(7, 'steampunk_diffusion', 'Steampunk', 'https://static.dezgo.com/samples/models2/d/o/steampunk_diffusion.jpg'),
(8, 'realistic_vision_1_3', 'Realistic Vision 1.3', 'https://static.dezgo.com/samples/models2/d/o/realistic_vision_1_3.jpg'),
(9, 'anything_4_0', 'Anything 4.0 (Anime style)', 'https://static.dezgo.com/samples/models2/d/o/anything_4_0.jpg'),
(10, 'basil_mix', 'Basil Mix (Realistic)', 'https://static.dezgo.com/samples/models2/d/o/basil_mix.jpg'),
(11, 'dh_classicanime', 'DH Classic Anime (Retro Anime)', 'https://static.dezgo.com/samples/models2/d/o/dh_classicanime.jpg'),
(12, 'disco_diffusion_style', 'Disco Diffusion Style', 'https://static.dezgo.com/samples/models2/d/o/disco_diffusion_style.jpg'),
(13, 'double_exposure_diffusion', 'Double Exposure Diffusion', 'https://static.dezgo.com/samples/models2/d/o/double_exposure_diffusion.jpg'),
(14, 'dreamshaper', 'Dreamshaper', 'https://static.dezgo.com/samples/models2/d/o/dreamshaper.jpg'),
(15, 'duchaiten_anime', 'Duchaiten Anime (3D effect)', 'https://static.dezgo.com/samples/models2/d/o/duchaiten_anime.jpg'),
(16, 'duchaiten_darkside', 'Duchaiten Darkside', 'https://static.dezgo.com/samples/models2/d/o/duchaiten_darkside.jpg'),
(17, 'emoji_diffusion', 'Emoji Diffusion', 'https://static.dezgo.com/samples/models2/d/o/emoji_diffusion.jpg'),
(18, 'ely_orange_mix', 'Ely Orange Mix (Anime)', 'https://static.dezgo.com/samples/models2/d/o/ely_orange_mix.jpg'),
(19, 'foto_assisted_diffusion', 'Foto Assisted Diffusion', 'https://static.dezgo.com/samples/models2/d/o/foto_assisted_diffusion.jpg'),
(20, 'iconsmi_appiconsmodelforsd', 'Mobile App Icons', 'https://static.dezgo.com/samples/models2/d/o/iconsmi_appiconsmodelforsd.jpg'),
(21, 'inkpunk_diffusion', 'Inkpunk Diffusion', 'https://static.dezgo.com/samples/models2/d/o/inkpunk_diffusion.jpg'),
(22, 'lowpoly_world', 'Lowpoly World', 'https://static.dezgo.com/samples/models2/d/o/lowpoly_world.jpg'),
(23, 'paint_journey_2_768px', 'Paint Journey 2 (Oil Painting)', 'https://static.dezgo.com/samples/models2/d/o/paint_journey_2_768px.jpg'),
(24, 'redshift_diffusion_768px', 'Redshift Diffusion', 'https://static.dezgo.com/samples/models2/d/o/redshift_diffusion_768px.jpg'),
(25, 'stablediffusion_inpaint_1', 'Inpaint 1', 'https://static.dezgo.com/samples/models2/d/o/stablediffusion_inpaint_1.jpg'),
(26, 'stablediffusion_inpaint_2', 'Inpaint 2', 'https://static.dezgo.com/samples/models2/d/o/stablediffusion_inpaint_2.jpg'),
(27, 'synthwavepunk_v2', 'Synthwave Punk v2', 'https://static.dezgo.com/samples/models2/d/o/synthwavepunk_v2.jpg'),
(28, 'tshirt_diffusion', 'T-shirt Diffusion', 'https://static.dezgo.com/samples/models2/d/o/tshirt_diffusion.jpg'),
(29, 'vectorartz_diffusion', 'Vector Art Diffusion', 'https://static.dezgo.com/samples/models2/d/o/vectorartz_diffusion.jpg'),
(30, 'stable_diffusion_fluidart', 'Fluid Art', 'https://static.dezgo.com/samples/models2/d/o/stable_diffusion_fluidart.jpg'),
(31, 'stable_diffusion_voxelart', 'Voxel Art', 'https://static.dezgo.com/samples/models2/d/o/stable_diffusion_voxelart.jpg'),
(32, 'stable_diffusion_papercut', 'Paper Cut Art', 'https://static.dezgo.com/samples/models2/d/o/stable_diffusion_papercut.jpg');
This block of code will submit the form and return the image and insert it into your database. Make sure you have your database set up before running submitting the form.
<?php
//This function will select model/style from db and display in select dropdown in form
function txt2img_styles()
{
global $db;
$sql = "SELECT id,op_value,display FROM txt2img_styles ORDER BY id ASC";
$statement = $db->prepare($sql);
$statement->execute();
$result = $statement->fetchAll();
foreach($result as $row)
{
echo"<option id='".$row['id']."' value='".$row['op_value']."'>".$row['display']."</option>";
}
}
//submit form and check for errors
if(isset($_POST['submit']))
{
if($_POST['model'] == '')
{
$err_style = "<div class='alert alert-danger'>Please select a style for your image</div>";
}
else if($_POST['description'] == '')
{
$err_desc = "<div class='alert alert-danger'>You must type in a description to make an image</div>";
}
else
{
$description = rawurlencode($_POST['description']); //we need rawurlencode to replace blank spaces and commas with %2C%20 for the prmpt
$db_descript = $_POST['description']; //Another description to be posted to database
$style = $_POST['model'];
$curl = curl_init();
$details = "prompt=".$description."&guidance=7&steps=30&sampler=euler_a&upscale=2&negative_prompt=ugly%2C%20tiling%2C%20poorly%20drawn%20hands%2C%20poorly%20drawn%20feet%2C%20poorly%20drawn%20face%2C%20out%20of%20frame%2C%20extra%20limbs%2C%20disfigured%2C%20deformed%2C%20body%20out%20of%20frame%2C%20blurry%2C%20bad%20anatomy%2C%20blurred%2C%20watermark%2C%20grainy%2C%20signature%2C%20cut%20off%2C%20draft&model=".$style."";
curl_setopt_array($curl, [
CURLOPT_URL => "https://dezgo.p.rapidapi.com/text2image",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => $details,
CURLOPT_HTTPHEADER => [
"X-RapidAPI-Host: dezgo.p.rapidapi.com",
"X-RapidAPI-Key: YOUR_API_KEY_HERE", //get your api key from RapidAPI.com
"content-type: application/x-www-form-urlencoded"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if($err)
{
echo "cURL Error #:" . $err;
}
else
{
$base64ImageData = base64_encode($response); //converts binary data to image
$data = [
'imageData' => $base64ImageData
];
$jsonData = json_encode($data); //converts binary to json for database entry
$sql = "INSERT INTO text2img (data_json, description) VALUES (:jsonData, :db_descript)";
$statement = $db->prepare($sql);
$statement->bindParam(':jsonData' , $jsonData, PDO::PARAM_STR);
$statement->bindParam(':db_descript' , $db_descript, PDO::PARAM_STR);
try
{
$statement->execute();
}
catch (PDOException $e)
{
echo $e;
}
}
}
}
?>
This block of Jquery will display the style/model based on the users selected option before the form is submitted. We will pull this information from the database in the get-style.php file near the bottom of the page.
<script>
$(document).ready(function(){
$("#style_select").change(function(){
var id = $(this).find(":selected").attr("id"); // Get the id of the selected option
//alert(id);
$.ajax({
url: 'get-style.php',
type: 'POST',
data: {id: id}, // Send the selected option's id
success: function(response) {
// Update the #img-div with the response data
$('#img-div').html(response);
},
error: function() {
// Handle errors if the AJAX request fails
console.error('AJAX request failed');
}
});
});
});
</script>
This is the form for submitting and error messages will be displayed if there is no description or style selected
<?php
//echo errors if description or style not complete/selected
if(isset($err_desc))
{
echo $err_desc;
}
if(isset($err_style))
{
echo $err_style;
}
?>
<form action="" method="post">
<div class="mb-2">
<textarea type="text" name="description" class="form-control" rows="6" placeholder="Be as descriptive as possible"></textarea>
</div>
<div class="mb-2">
<select id="style_select" name="model" class="form-select form-select-lg mb-3">
<option selected value=''>Select Model/Style</option>
<?php txt2img_styles() ?>
</select>
</div>
<div class="mb-2">
<button class="btn btn-primary" type="submit" name="submit">Generate Image</button>
</div>
</form>
Place this chunck of code just below the closing form tag. This will display the returned image and the img-div will display the selected model/style.
<?php
if(isset($base64ImageData))
{
echo "<img class='img-fluid' src='data:image/png;base64, ".$base64ImageData."' alt='Image Description'>";
}
?>
</div>
<div id="img-div" class="col-12 col-md-6">
<!-- Load model/style image here -->
</div>
This block of code will take previous generated images stored in database and display them at the bottom o fthe page. With some CSS we can add a hover overlay that will display the description that was entered to generate the displayed image.
<div class="row">
<h5>Previuos created AI text to image results</h5>
<?php
$sql = "SELECT id,data_json,description FROM text2img ORDER BY id DESC";
$statement = $db->prepare($sql);
$statement->execute();
$result = $statement->fetchAll();
$thumb_img = "";
foreach($result as $row)
{
$id = $row['id'];
// Decode the JSON to a PHP array or object
$bin = json_decode($row['data_json'], true); // Set the second parameter to true for an associative array
$string = implode($bin);
$thumb_img .= "<div class='img-container'>
<div class=content mb-5>
<img class='img thumbnail img-fluid' src='data:image/png;base64, ".$string."' alt=''>
<div class=content-overlay></div>
<div class=content-details fadeIn-top>
<h4>".$row['description']."</h4>
</div>
</div>
</div>";
}
?>
<div class="col-12">
<?php
echo $thumb_img;
?>
</div>
</div>
Save the following code in a seperate file called get-style.php. This code will display the image from the database for the selected model/style
<?php
include '../includes/connect.php';
if (isset($_POST['id']))
{
$id = $_POST['id'];
$sql = "SELECT id,op_value,img FROM txt2img_styles WHERE id = $id";
$statement = $db->prepare($sql);
$statement->execute();
$result = $statement->fetchAll();
foreach($result as $row)
{
echo "<img class='img-fluid' id='".$row['id']."' src='".$row['img']."'>";
}
}
?>
I have the this little block of JS at the bottom of the page. It makes sure the form is cleared after submission and won't re-submit if page is refreshed.
<script>
if (window.history.replaceState )
{
window.history.replaceState( null, null, window.location.href );
}
</script>
CSS for image thumbnail overlay.
/*text2img overlay*/
.img-container{
padding: 1em 0;
float: left;
width: 50%;
}
@media screen and (max-width: 640px){
.img-container{
display: block;
width: 100%;
}
}
@media screen and (min-width: 900px){
.img-container{
width: 33.33333%;
}
}
.img-container .title{
color: #1a1a1a;
text-align: center;
margin-bottom: 10px;
}
.content {
position: relative;
width: 90%;
max-width: 400px;
overflow: hidden;
}
.content .content-overlay {
background: rgba(0,0,0,0.7);
position: absolute;
width: 100%;
left: 0;
top: 0;
bottom: 0;
right: 0;
opacity: 0;
-webkit-transition: all 0.4s ease-in-out 0s;
-moz-transition: all 0.4s ease-in-out 0s;
transition: all 0.4s ease-in-out 0s;
}
.content:hover .content-overlay{
opacity: 1;
}
.content-image{
width: 100%;
}
.content-details {
position: absolute;
text-align: center;
padding-left: 1em;
padding-right: 1em;
width: 100%;
top: 50%;
left: 50%;
opacity: 0;
-webkit-transform: translate(-50%, -50%);
-moz-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
-webkit-transition: all 0.3s ease-in-out 0s;
-moz-transition: all 0.3s ease-in-out 0s;
transition: all 0.3s ease-in-out 0s;
}
.content:hover .content-details{
top: 50%;
left: 50%;
opacity: 1;
}