Skip to content

Instantly share code, notes, and snippets.

@tharmann
Last active January 7, 2019 20:37
Show Gist options
  • Select an option

  • Save tharmann/5a3bd7eb92756f784ad6c2b0e7c32e46 to your computer and use it in GitHub Desktop.

Select an option

Save tharmann/5a3bd7eb92756f784ad6c2b0e7c32e46 to your computer and use it in GitHub Desktop.
A little C program that recursively resizes images with variable minimum edge and quality values. Also supports an optional 'dry_run' switch. Utilizes MagickWand.
#include <sys/types.h>
#include <stdlib.h>
#include <dirent.h>
#include <stdio.h>
#include <string.h>
#include <wand/MagickWand.h>
int count = 0;
void processdir(const char *name, const int min_edge, const int quality, const int dry_run) {
DIR *dir;
struct dirent *entry;
const char *img_exts[] = {"jpg","jpeg","JPG","JPEG","png","PNG", "gif", "GIF"}, dot = '.';
char path[1024], fullname[1024], command[1024];
char *ext;
int i, isimg, w, h;
MagickBooleanType status;
MagickWand *magick_wand;
if (!(dir = opendir(name)))
return;
while ((entry = readdir(dir)) != NULL) {
if (entry->d_type == DT_DIR) {
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
continue;
snprintf(path, sizeof(path), "%s/%s", name, entry->d_name);
processdir(path, min_edge, quality, dry_run);
} else {
isimg = 0;
ext = strrchr(entry->d_name, dot);
if (ext == NULL)
continue;
for (i=0; i < 8; i++) {
if (strcmp(img_exts[i],ext + 1) == 0) {
isimg = 1;
}
}
if (isimg) {
snprintf(fullname, sizeof(fullname), "%s/%s", name, entry->d_name);
MagickWandGenesis();
magick_wand = NewMagickWand();
status = MagickPingImage(magick_wand,fullname);
if (status != MagickFalse) {
w = MagickGetImageWidth(magick_wand);
h = MagickGetImageHeight(magick_wand);
if ( w > min_edge || h > min_edge ) {
snprintf(command, sizeof(command), "mogrify -scale \'%dx%d>\' \"%s/%s\" -quality %d", min_edge, min_edge, name, entry->d_name, quality);
if (dry_run) {
printf("%s\n", fullname);
} else {
printf("%s\n", command);
system(command);
}
count++;
}
} else {
printf("There was a problem processing file: %s\n", fullname);
}
magick_wand = DestroyMagickWand(magick_wand);
MagickWandTerminus();
}
}
}
closedir(dir);
}
int main(int argc, char *argv[]) {
if (argc < 3) {
printf("Required params (int)min_edge and (int)quality missing.\n");
printf("e.g. #>recursive_mog 1024 80\n");
printf("Where 1024 is the minimum width or height in pixels of the images you wish to resize. And 80 is the quality output of the resulting image after resizing.\n");
printf("Optionally, you can throw the 'dry_run' switch at the end of the command to only print which files would be modified.\n");
return 1;
} else {
const int min = atoi(argv[1]);
const int qual = atoi(argv[2]);
int dry;
if (min == 0 || qual == 0) {
printf("Values for min_edge and quality were provided but are not valid integers.\n");
return 1;
} else {
if (argv[3]) {
dry = 1;
} else {
dry = 0;
}
processdir(".", min, qual, dry);
if (dry) {
printf("All Done. %d Files Would Have Been Modified.\n", count);
} else {
printf("All Done. %d Files Modified.\n", count);
}
return 0;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment