// 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"));