How to extract positive prompt from a png file made with forge or a1111 or any sd png that has the prompt in the parameters metadata. (in linux)
steps
create a c file for the script
nano extract_parameters.cmake sure libpng-dev is installed
sudo apt-get install libpng-devpaste in the script:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <libpng16/png.h>
#include <sys/stat.h>
// Function to check if a file has a .png extension
int is_png(const char *filename) {
const char *ext = strrchr(filename, '.');
return ext && strcmp(ext, ".png") == 0;
}
// Function to extract "parameters" metadata
void extract_parameters(const char *png_file, const char *output_dir) {
printf("Processing file: %s\n", png_file);
FILE *fp = fopen(png_file, "rb");
if (!fp) {
perror("Failed to open PNG file");
return;
}
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
png_infop info_ptr = png_create_info_struct(png_ptr);
if (!png_ptr || !info_ptr) {
fprintf(stderr, "Failed to initialize libpng\n");
fclose(fp);
return;
}
if (setjmp(png_jmpbuf(png_ptr))) {
fprintf(stderr, "Error during PNG processing\n");
fclose(fp);
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
return;
}
png_init_io(png_ptr, fp);
png_read_info(png_ptr, info_ptr);
png_textp text_ptr;
int num_text;
if (png_get_text(png_ptr, info_ptr, &text_ptr, &num_text) > 0) {
printf("Found %d text entries in file: %s\n", num_text, png_file);
for (int i = 0; i < num_text; i++) {
printf("Key: %s\n", text_ptr[i].key);
if (strcmp(text_ptr[i].key, "parameters") == 0) {
char *parameters = text_ptr[i].text;
// Find "Negative prompt:" and truncate
char *negative_prompt = strstr(parameters, "Negative prompt:");
if (negative_prompt) {
*negative_prompt = '\0';
}
// Print the truncated value
printf("Extracted parameters metadata (truncated):\n%s\n", parameters);
// Determine output file path
char output_file[1024];
const char *base_name = strrchr(png_file, '/'); // Get the base name
base_name = base_name ? base_name + 1 : png_file; // Skip the slash if present
if (output_dir) {
// Save to the specified output directory
snprintf(output_file, sizeof(output_file), "%s/%.*s.txt",
output_dir,
(int)(strrchr(base_name, '.') - base_name),
base_name);
} else {
// Save in the same directory as the input PNG
char input_dir[1024];
strncpy(input_dir, png_file, strrchr(png_file, '/') - png_file);
input_dir[strrchr(png_file, '/') - png_file] = '\0';
snprintf(output_file, sizeof(output_file), "%s/%.*s.txt",
input_dir,
(int)(strrchr(base_name, '.') - base_name),
base_name);
}
// Write to file
FILE *out_fp = fopen(output_file, "w");
if (out_fp) {
fprintf(out_fp, "%s", parameters);
fclose(out_fp);
printf("Extracted metadata written to %s\n", output_file);
} else {
perror("Failed to write metadata file");
}
break;
}
}
} else {
printf("No metadata found in file: %s\n", png_file);
}
fclose(fp);
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
}
// Function to process a directory
void process_directory(const char *dir_path, const char *output_dir) {
DIR *dir = opendir(dir_path);
if (!dir) {
perror("Failed to open directory");
return;
}
struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
if (entry->d_type == DT_REG && is_png(entry->d_name)) {
char full_path[1024];
snprintf(full_path, sizeof(full_path), "%s/%s", dir_path, entry->d_name);
extract_parameters(full_path, output_dir);
}
}
closedir(dir);
}
int main(int argc, char *argv[]) {
if (argc < 2) {
fprintf(stderr, "Usage: %s <directory> [output_directory]\n", argv[0]);
return EXIT_FAILURE;
}
const char *input_dir = argv[1];
const char *output_dir = NULL;
if (argc >= 3) {
output_dir = argv[2];
// Check if output directory exists, create it if necessary
struct stat st;
if (stat(output_dir, &st) == -1) {
if (mkdir(output_dir, 0700) == -1) {
perror("Failed to create output directory");
return EXIT_FAILURE;
}
} else if (!S_ISDIR(st.st_mode)) {
fprintf(stderr, "Error: Output path is not a directory\n");
return EXIT_FAILURE;
}
}
process_directory(input_dir, output_dir);
return EXIT_SUCCESS;
}
Compile the program:
gcc extract_parameters.c -o extract_parameters -lpngRun program
./extract_parameters <input_directory> <output_directory>you can run it with just input_directory and it will save the .txt file to the input_directory. this will run very fast.

