← All articles
Published December 8, 2024by Gablingus
How to extract png positive prompt and save to txt file in the same directory (linux)
81 views1 reactions0 comments on CivitAI6 collected
image taginglora trainingdata prepextract metadata

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.