Last active
January 7, 2019 20:37
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #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