I'm working on an ESP32 project to send a Base64-encoded image to an API using HTTP POST requests. Although I can successfully encode the image and verify its length, the JSON payload being sent does not include the Base64 image data. The API response indicates an error, stating that "astica cognitive services is unable to process the request." I need help ensuring that the Base64 image is correctly attached to the payload before sending it. Any advice or guidance on how to troubleshoot this issue would be greatly appreciated!
The image is stored on the SD card, which is subsequently fetched in chunks, encoded in base64, and attached to a String. We do this until all the chunks of the image are read and encoded. Once that occurs, I attempt to attach the payload to a JSON string payload, which subsequently invokes Astica's API through a POST request. However, the payload does not seem to attach the encoded image and returns an error.
Here is the code for reference:
#include <WiFi.h>
#include <HTTPClient.h>
#include <SD.h>
#include <Base64.h>
#include <Arduino.h>
#include <SD_MMC.h>
#include <SPIFFS.h>
#include <FFat.h>
const char* ssid = "MY_SSID";
const char* password = "MY_PASSWORD";
const char* asticaAPIKey = "API_KEY";
const char* asticaAPIEndpoint = "https://vision.astica.ai/describe";
const int chipSelect = 13;
// Function to read the image and encode it in Base64
String getImageBase64Encoding(String imagePath) {
File imageFile = SD.open(imagePath);
if (!imageFile) {
Serial.println("Failed to open file");
return "";
}
const size_t CHUNK_SIZE = 256; // Read in smaller chunks
uint8_t buffer[CHUNK_SIZE]; // Allocate on stack for efficiency
String encodedImage = "";
while (imageFile.available()) {
size_t bytesRead = imageFile.read(buffer, CHUNK_SIZE);
if (bytesRead > 0) {
String chunk = base64::encode(buffer, bytesRead);
encodedImage += chunk;
}
yield(); // Allow other tasks to run
}
imageFile.close();
return encodedImage;
}
// Function to create the JSON payload
// Function to create the JSON payload
// Function to create the JSON payload
String createPayload(String base64Image) {
String payload = "{";
payload += "\"tkn\":\"" + String(asticaAPIKey) + "\",";
payload += "\"modelVersion\":\"2.5_full\",";
payload += "\"visionParams\":\"gpt,describe,objects,faces\",";
payload += "\"input\":\"" + base64Image + "\",";
payload += "\"gpt_prompt\":\"Describe the room and environment, objects, people, and actions in no more than two sentences\",";
payload += "\"prompt_length\":30,";
payload += "\"objects_custom_kw\":\"\"";
payload += "}";
// Print payload information
Serial.println("Payload created. Length: " + String(payload.length()));
return payload;
}
// Function to send an HTTP POST request to the API
void sendAsticaRequest(String payload) {
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
http.begin(asticaAPIEndpoint);
http.addHeader("Content-Type", "application/json");
// Send the POST request
int httpResponseCode = http.POST(payload);
// Check the response
if (httpResponseCode > 0) {
String response = http.getString();
Serial.println("Response: " + response);
} else {
Serial.println("Error sending POST request: " + String(httpResponseCode));
}
http.end();
} else {
Serial.println("WiFi not connected");
}
}
void setup() {
Serial.begin(115200);
// Connect to WiFi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi...");
}
Serial.println("Connected to WiFi");
// Initialize the SD card
if (!SD.begin(chipSelect)) {
Serial.println("SD card initialization failed!");
return;
}
Serial.println("SD card initialized.");
}
void loop() {
// Path to the image on the SD card
String imagePath = "/test.jpg";
// Read and encode the image
String base64Image = getImageBase64Encoding(imagePath);
if (base64Image == "") {
Serial.println("Failed to read image");
return;
}
// Output the length of the base64 string
Serial.println("Base64 image length: " + String(base64Image.length()));
// Create payload with base64-encoded image
String payload = createPayload(base64Image);
Serial.println("Payload size: " + String(payload.length()));
// Log the complete payload for debugging
Serial.println("Full payload: " + payload);
// Send the payload to the API
sendAsticaRequest(payload);
Serial.println("____________________________________");
delay(6000); // Wait for 6 seconds between requests
}
Any help will be appreciated.