Generate Images in Google Drive with Stability AI
AI, Stability AI, Google Drive, Google Apps Script, API
AI images generators are cool, but unless you can create images that are easy to access and share, they lack the ability to play a role in your technology ecosystem.
Stability AI is a fun and useful AI platform. It is also affordable. I am not going to review how to setup an account, I found it pretty easy. I have only been using the text-to-image API, but they seem to do much more.
Here is a demo of the sandbox. It shows you the code, and what the values can do:
(Maximize the video to read the code)
Creating Visitor Badges
I am working on a personal project. The goal is to have two AIs work together to create unique visitor badges. When a visitor interacts with a kiosk, they get a fun sticker badge to wear. The design is based on colors assigned to days-of-the-week and the current weather:
function getColorForToday() {
var colors = [
"White", // Sunday
"Red", // Monday
"Blue", // Tuesday
"Green", // Wednesday
"Yellow", // Thursday
"Purple", // Friday
"Gray" // Saturday
];
var today = new Date();
var dayOfWeek = today.getDay(); // Gets the day of the week (0 for Sunday, 6 for Saturday)
var colorOfTheDay = colors[dayOfWeek]; // Selects the color based on the day of the week
// Logger.log(colorOfTheDay); // Outputs the color to the log
return colorOfTheDay;
}
OpenAI reads data from a weather API and then summarizes it into four words:
// Declare the global variable at the top of the script
var globalOpenAIResponse;
function callOpenAI() {
getCurrentWeatherData();
var aiModel = myAIModel();
var model = aiModel; // Specify the model
var temperature = 0.7; // Set the creativity of the model
var maxTokens = 200; // Limit the maximum number of tokens in the response
var apiKey = myOpenAIKey(); // Function to retrieve your actual API Key
// Access the global weather data
var weatherPrompt = `${globalWeatherData.weather[0].description}`;
//Logger.log(weatherPrompt);
var requestBody = {
"model": model,
"temperature": temperature,
"max_tokens": maxTokens,
"messages": [
{
"role": "system",
"content": "You can only generate four words. No punctuation"
},
{
"role": "user",
"content":'Given the weather data'+ weatherPrompt + 'describe the main weather condition and what the temperature feels like in four words without punctuation'
}
]
};
var requestOptions = {
"method": "POST",
"headers": {
"Content-Type": "application/json",
"Authorization": "Bearer " + apiKey
},
"payload": JSON.stringify(requestBody)
};
var response = UrlFetchApp.fetch("https://api.openai.com/v1/chat/completions", requestOptions);
var jsonResponse = JSON.parse(response.getContentText());
var modelResponse = jsonResponse.choices[0].message.content;
// Store the response in the global variable
globalOpenAIResponse = modelResponse;
// Log the response to the console
Logger.log(globalOpenAIResponse);
}
Using weather data adds some randomness, but it is not necessary. There are many ways to approach it. Weather data from the an API is hard to read, and the challenge of promting the AI to get exactly what I want is part of the project.
The four words from OpenAI are inserted into the Stability AI API call, to generate the badge:
function generateAndSaveImage() {
const url = myStabilityURL();
const apiKey = myStabilityAIKey(); // Secure your API key properly, possibly using script properties
const folderId = myImageFolder(); // Specific Google Drive folder ID
var theDay = getColorForToday();
var randomStyle = getRandomStyle();
callOpenAI();
// Logger.log(globalOpenAIResponse);
//Logger.log(randomStyle);
//Logger.log(theDay);
Logger.log(globalOpenAIResponse);
const payload = {
"steps": 40,
"width": 1024,
"height": 1024,
"seed": 0,
"cfg_scale": 5,
"samples": 1,
"style_preset": randomStyle,
"text_prompts": [
{
"text": globalOpenAIResponse+" "+theDay+" "+ "High School",
"weight": 1
},
{
"text": "blurry, bad, nudity",
"weight": -1
}
]
};
const options = {
'method': 'post',
'contentType': 'application/json',
'headers': {
'Authorization': 'Bearer ' + apiKey
},
'payload': JSON.stringify(payload)
};
const response = UrlFetchApp.fetch(url, options);
if (response.getResponseCode() === 200) {
const jsonResponse = JSON.parse(response.getContentText());
const folder = DriveApp.getFolderById(folderId); // Get the specific folder by ID
jsonResponse.artifacts.forEach(function(artifact) {
//const imageBlob = Utilities.newBlob(Utilities.base64Decode(artifact.base64), 'image/png', `txt2img_${artifact.seed}.png`);
const imageBlob = Utilities.newBlob(Utilities.base64Decode(artifact.base64), 'image/png', `txt2img_badge.png`);
folder.createFile(imageBlob); // Create the file in the specified folder
});
} else {
console.error('Failed to generate image: ' + response.getContentText());
}
insertImageToSlide();
}
Here is what it looks like
Here is the code to save the output to Google Drive, and place it in a Slide:
function insertImageToSlide() {
try {
// IDs
var slideId = myBadgeSlide();
var folderId = myImageFolder();
var imageName = myBadgeImage();
// Open the presentation
Logger.log('Opening presentation with ID: ' + slideId);
var presentation = SlidesApp.openById(slideId);
var slide = presentation.getSlides()[0];
// Remove all elements from the slide
var pageElements = slide.getPageElements();
for (var i = 0; i < pageElements.length; i++) {
pageElements[i].remove();
}
Logger.log('Opened presentation successfully');
// Retrieve the image file from the folder
Logger.log('Accessing folder with ID: ' + folderId);
var folder = DriveApp.getFolderById(folderId);
Logger.log('Folder name: ' + folder.getName());
var files = folder.getFilesByName(imageName);
if (files.hasNext()) {
var file = files.next();
Logger.log('Found image file: ' + file.getName());
var blob = file.getBlob();
// Insert the image into the slide
slide.insertImage(blob);
Logger.log('Image inserted successfully');
} else {
Logger.log('Image not found in the specified folder');
}
} catch (error) {
Logger.log('Error: ' + error.toString());
}
deleteImageFromFolder();
}
Enjoy AI Images!
Copyright © Domain Seven LLC. All rights reserved.
For permissions to use or share any content behind our paywall, please email us at: tonydeprato@domain7.tech .