Code viewer for World: Which Text-to-Image Model ...

// Cloned by Maksymilian Frackowiak on 11 Nov 2024 from World "Chat with GPT model" by Starter user 
// Please leave this clone trail here.

//finished two image generations given prompt
//finished api to compare accuracy of images
//finished debugging and error handling


// can POST to this 3rd party URL
const apiurl = 'https://open-ai21.p.rapidapi.com/texttoimage2';
const apiurl2 = 'https://ai-image-generator14.p.rapidapi.com/';
const apiurl3 = 'https://www.nyckel.com/v1/functions/dog-breed-identifier/invoke';


//  initialize API key and prompt:

var rapidkey = "";
var nyckelkey = "";
var thedog = "";
var theprompt = "";


// referenced from "Chat with GPT model", although modified with custom css and different text
document.write ( `
<!DOCTYPE html>
<html lang="en">
<head>
  <style>
    body {
    margin: 20px;
    padding: 20px;
    font-family: Helvetica;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    background: url("uploads/frackom26/dogwallpaper2.jpg") no-repeat center center fixed;
    -webkit-background-size: cover;
    -moz-background-size: cover;
    -o-background-size: cover;
    background-size: cover;
    }
    p {
    margin: 5px;
    padding: 5px;
    }
    .image-container{
    display:flex;
    justify-content: left;
    }
    .image-overlay{
    position: relative;

    }
    .image-overlay img{
    width:100%;
    display:block;
    }

    .overlay {
    position:absolute;
    bottom:0;
    background: rgb(0,0,0);
    background: rgba(0,0,0,0.5);
    color:#f1f1f1;
    width:70%;
    transition: .5s ease;
    opacity: 0;
    color:white;
    font-size:20px;
    padding:20px;
    text-align:left;
    }
    .image-overlay:hover .overlay{
    opacity:1;
    }
  </style>
</head>
<body>
<h1>Which Text-to-Image Model has the Most Accurate Dogs?</h1>

<p>Generate AI Images of dogs using OpenAI's Dall-E-3 and Sapienvault's Image Generator through <a href="https://rapidapi.com/hub">
Rapid API.</a> </p>
<p>Compare their accuracy through <a href="https://www.nyckel.com/pretrained-classifiers/dog-breed-identifier/">Nyckel's</a>
Dog Breed Classifier AI API, which can identify 120 breeds of dogs!</p>

<pre>

</pre>

<h2> Getting your API Key </h2>

<p>Register for free at <a href="https://rapidapi.com/auth/sign-up">RapidAPI</a> and 
<a href="https://login.nyckel.com/u/signup?state=hKFo2SBTOTBqWkRILXVtZGhxV1R4NWI0Tnk5UjZ6azQybUZhbqFur3VuaXZlcnNhbC1sb2dpbqN0aWTZIDVnOWxzeWhpWGJnek1fNmFqZkxEeHZWaEh6MHpLbmZlo2NpZNkgSXZ5T2pLUGtNdWFyRzM2SG9sWG9zVFNQTVZyWk9MbTk">
Nyckel</a> to get your API keys!</p>  
<p>To view your RapidAPI Key, subscribe to <a href="https://rapidapi.com/rphrp1985/api/open-ai21">OpenAI</a>
and <a href="https://rapidapi.com/sapienvault-ai-sapienvault-ai-default/api/ai-image-generator14">Sapienvault</a>
and copy it from "X-RapidAPI-Key".</p>
<p>To view your Nyckel API Key, go to your <a href="https://www.nyckel.com/console/keys">API Keys</a>,
scroll down to the example response and retrieve it from "access_token".</p>
<p>This World will never store your API key. 
You can view the <a href='https://ancientbrain.com/viewjs.php?world=2850716357'> source code</a>  to see that is true!</p>
<br>
<div id=enterkey>
Enter RapidAPI key: 
	<input    style='width:25vw;'   maxlength='2000'   NAME="apikey"    id="apikey"       VALUE='' >  
	<button style="background-color: blue" onclick='setRapidKey();'  class=ab-normbutton >Set API key</button>
<br> <br>
Enter Nyckel key:  
	<input    style='width:25vw;'    maxlength='2000'   NAME="apikey"    id="apikey2"       VALUE='' >  
	<button style="background-color: blue" onclick='setNyckelKey();'  class=ab-normbutton >Set API key</button>
	<p id="messageDisplay"></p>
	<p id="messageDisplay2"></p>
</div>

<div style="width:55vw; background-color:white;  border: 1px solid black; margin:20; padding: 20px;">
<h3> Enter a Dog! Proper spelling and capitalisation is important. </h3>
<INPUT style="width:50vw;" id=me value="Golden Retriever" >
<button style="background-color: blue" onclick="sendChat();"     class=ab-normbutton > Send </button> 
<p id ="apiContent"></p>
</div>

<div style="width:55vw; background-color:#ffffcc;  border: 1px solid black; margin:20; padding: 20px;">
<h3> Image Generations </h3>
<div id="image-container" class="image-container">
 </div>
<h3> Dog Identifier Results</h3>
<p> Note: If the generated image is classified as "Painting", then Nyckel failed to identify the dog breed.</p>
<div id="percentage-container" class="percentage-container"></div>
</div>
 
 <p> <i> Remember that generated images can be completely inaccurate.<br> 
 All LLM systems <a href="https://www.google.com/search?q=image+models+hallucination"> "hallucinate"</a>.
 It is how they work. </i> </p>

<pre>

</pre>
</body>
</html>
` );

// takes user inputted API Key and sets it to the RapidAPI key
function setRapidKey() {
    rapidkey =  jQuery("input#apikey").val();
	rapidkey = rapidkey.trim();
    const messageDisplay = document.getElementById('messageDisplay');
	if(rapidkey != ""){
	    messageDisplay.textContent ="RapidAPI key has been set!";
	}
	else{
	    messageDisplay.textContent = "Nothing submitted, please try again.";
    }
    //console.log(rapidkey);
}

// takes user inputted API Key and sets it to the Nyckel API Key
function setNyckelKey() {
    nyckelkey =  jQuery("input#apikey2").val();
	nyckelkey = nyckelkey.trim();
    const messageDisplay = document.getElementById('messageDisplay2');
	if(nyckelkey != ""){
	    messageDisplay.textContent ="Nyckel API key has been set!";
	}
	else{
	    messageDisplay.textContent = "Nothing submitted, please try again.";
    }
    //console.log(nyckelkey);
}


// creates the prompt with the user's chosen dog and sends it to APIs
function sendChat()
{
  clearContent("image-container");
  clearContent("percentage-container");
  thedog = jQuery("input#me").val();
  thedog = thedog.trim();
  thedog = capitalString(thedog);
  random = capitalString(getRandomWord());
  theprompt = "Detailed Realistic " + random + " Portrait Image of a " + thedog + " dog"
  promptDisplay = document.getElementById('apiContent');
  if(thedog != ""){
      promptDisplay.innerHTML=`Prompt: ${theprompt} has been sent! Please wait 1-2 minutes.`;
      fetchData(theprompt);
  }
  else{
      promptDisplay.textContent="Nothing inputted. Please try again.";
      
  }
  //console.log(theprompt);
  
}

// Enter will also set key and send chat:
// referenced from "Chat with GPT Model" starter world
document.getElementById('apikey').onkeydown   = function(event){ if (event.keyCode == 13)  setRapidKey(); };
document.getElementById('apikey2').onkeydown   = function(event){ if (event.keyCode == 13)  setNyckelKey(); };
document.getElementById('me').onkeydown = function(event) { if (event.keyCode == 13) sendChat(); };


// sends POST requests to image generator APIs
const fetchData = async (prompt) => {
    const options = {
	method: 'POST',
	headers: {
		'x-rapidapi-key': rapidkey,
		'x-rapidapi-host': 'open-ai21.p.rapidapi.com',
		'Content-Type': 'application/json'
	},
	
	body: JSON.stringify({
	    text: theprompt,
	    }),
    };
    const options2 = {
	method: 'POST',
	headers: {
		'x-rapidapi-key': rapidkey,
	 	'x-rapidapi-host': 'ai-image-generator14.p.rapidapi.com',
		'Content-Type': 'application/json'
	},

	body: JSON.stringify({
	    jsonBody: {
		    function_name: 'image_generator',
		    type: 'image_generation',
		    query: theprompt,
		    output_type: 'png'
	        }
		}),
    };
    //fetching and error handling OPENAI
	const response = await fetch(apiurl, options);
    if(!response.ok){
        handleError(response);
        return;
    }
    const data = await response.json();
    if(data.status == false){
        console.log(`Error ${data.error}`);
        handleError(data);
        return;
    }
    console.log(data);
    displayImage(data["generated_image"], "Dall-e-3");
	const response2 = await fetch(apiurl2, options2);
	const data2 = await response2.json();
	console.log(data2);
    displayImage(data2["message"]["output_png"], "Sapienvault");
	fetchDataBreed(data2["message"]["output_png"],"Sapienvault");
	fetchDataBreed(data["generated_image"],"Dall-e-3");
} 

// displays images with an overlay
function displayImage(url, String){
    const imgDiv = document.createElement("div");
    imgDiv.className = "image-overlay";
    const cover = document.createElement("div");
    cover.className = "overlay";
    cover.innerText = String;
    const imgElement = document.createElement("img");
    imgElement.src = url;
    imgElement.alt = "Generated image from API";
    imgElement.title = String;
    imgElement.style.width = '25vw';
    imgElement.style.height = 'auto';
    imgElement.style.paddingRight = "2vw";
    const imageContainer = document.getElementById("image-container");
    imgDiv.appendChild(imgElement);
    imgDiv.appendChild(cover);
    imageContainer.appendChild(imgDiv);
}

// for test cases
//const img1 = "https://thelandofwanderlust.com/wp-content/uploads/2024/08/20e4f8ef-10f1-414c-99e5-a9824210db1f-1024x1024.jpeg"
//const img2 = "https://karenhoglundphotography.com/wp-content/uploads/2023/02/Black-dog-1024x1024.jpg"

// sends generated images to Nyckel Dog Breed Identifier API
const fetchDataBreed = async (imgurl, String) => {
    const options = {
	method: 'POST',
	headers: {
		'Authorization': 'Bearer ' + nyckelkey,
        'Content-Type': 'application/json',
	},
	body: JSON.stringify({
	    "data": imgurl,
        }),
    };

	const response = await fetch(apiurl3, options);
	const result = await response.json();
	console.log(result);
	// some of the Dog Breed Identifier labels are not spelled correctly
	if (result["labelName"] == "Doberman") {
	    result["labelName"] = "Dobermann";
	}
	if (result["labelName"] == "Dalamatian") {
	    result["labelName"] = "Dalmatian";
	}
	const text = document.createElement("p");
	const identifier = document.createElement("p");
	if (result["labelName"] == thedog) {
	    identifier.innerText = "Identified correctly!";
	}
	else{
	    identifier.innerText = "Identified incorrectly."
	}
	const api = String;
	text.innerText = api + " - " + result["labelName"] + " - " + Math.round((result["confidence"] * 100)) + "% Confidence";
	const percentContainer = document.getElementById("percentage-container");
	percentContainer.appendChild(text);
	percentContainer.appendChild(identifier);
	console.log(result["labelName"]);
	console.log(Math.round((result["confidence"] * 100)));
}

// displays that an error occured to the user
function handleError(err) {
    console.log(err);
    promptDisplay = document.getElementById('apiContent');
    if (err.error == "server is busy"){
        promptDisplay.innerHTML = "Error! OpenAI server is busy, please try again later!";
    }
    else if (err.status == 403 || err.status == 401) {
        promptDisplay.innerHTML = "Error! Invalid API Key!";
    }
    else {
        promptDisplay.innerHTML = "Error! ???";
    }
}
//as the dog identifier api result has the dog identified with proper capitalisation,
//this function makes sure the user inputted dog also has proper capitalisation
function capitalString(str) {
    return str.split(' ').map(
        word => word.charAt(0).toUpperCase() + word.slice(1))
        .join(' ');
}

//clears text and images for when the user wants to generate another comparison
function clearContent(elementID) {
    document.getElementById(elementID).innerHTML = "";
}

//as the Sapienvault image generator would return the same image for a prompt,
// I created a function slightly randomize the prompts
function getRandomWord() {
    const words = ["front view", "side view", "bird's eye view", "from below view"];
    const randomIndex = Math.floor(Math.random() * words.length);
    return words[randomIndex]
}

//testing functions
//displayImage(img2, "Sapienvault");
//displayImage(img1, "Dall-e-3");
//fetchDataBreed(img2, "Sapienvault");
//fetchDataBreed(img1, "Dall-e-3");
//console.log(capitalString("golden retriever"));