croptool

Image cropping tool
git clone git://lumidify.org/croptool.git (fast, but not encrypted)
git clone https://lumidify.org/git/croptool.git (encrypted, but very slow)
Log | Files | Refs | README | LICENSE

commit 89b192cbe0b959ae29cbdf20e955452d39e235a2
parent a67eb3e9010ebafadb4553d430cd91a8a42ae8e7
Author: lumidify <nobody@lumidify.org>
Date:   Sun,  7 Mar 2021 11:55:03 +0100

Improve documentation; misc. other fixes

Diffstat:
MCHANGELOG | 2+-
MLICENSE | 2+-
MMakefile | 5+++--
Mcroptool.1 | 23++++++++++++++---------
Mcroptool.c | 61+++++++++++++++++++++++++++++++++++++++----------------------
Mcroptool_crop.1 | 2+-
Mcroptool_crop.c | 2+-
7 files changed, 60 insertions(+), 37 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG @@ -1,4 +1,4 @@ -1.1 -> 1.2-dev +1.1 -> 1.2.0-dev * Rewrite using Xlib and Imlib2 * Add command-line options and man pages * Add automatic resizing of image when resizing window diff --git a/LICENSE b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2021 lumidify <nobody[at]lumidify.org> +Copyright (c) 2021 lumidify <nobody@lumidify.org> Permission to use, copy, modify, and distribute this software for any purpose with or without fee is hereby granted, provided that the above diff --git a/Makefile b/Makefile @@ -1,7 +1,7 @@ .POSIX: NAME = croptool -VERSION = 1.2-dev +VERSION = 1.2.0-dev PREFIX = /usr/local MANPREFIX = ${PREFIX}/man @@ -9,6 +9,7 @@ MANPREFIX = ${PREFIX}/man BIN = ${NAME} croptool_crop SRC = ${BIN:=.c} MAN1 = ${BIN:=.1} +MISCFILES = Makefile README CHANGELOG LICENSE TODO CFLAGS += -D_POSIX_C_SOURCE=200809L `pkg-config --cflags x11` `imlib2-config --cflags` LDFLAGS += `pkg-config --libs x11` `imlib2-config --libs` -lm @@ -45,7 +46,7 @@ clean: dist: rm -rf "${NAME}-${VERSION}" mkdir -p "${NAME}-${VERSION}" - cp -f ${MAN1} ${SRC} Makefile "${NAME}-${VERSION}" + cp -f ${MAN1} ${SRC} ${MISCFILES} "${NAME}-${VERSION}" tar cf - "${NAME}-${VERSION}" | gzip -c > "${NAME}-${VERSION}.tar.gz" rm -rf "${NAME}-${VERSION}" diff --git a/croptool.1 b/croptool.1 @@ -1,4 +1,4 @@ -.Dd March 6, 2021 +.Dd March 7, 2021 .Dt CROPTOOL 1 .Os .Sh NAME @@ -16,8 +16,8 @@ .Sh DESCRIPTION .Nm shows each of the given images and allows a cropping rectangle to be drawn. -On exit, the cropping command is printed out for each of the files. -If a file was skipped, nothing is printed out for it. +On exit, the cropping command is printed for each of the files. +If a file was skipped, nothing is printed for it. .Sh OPTIONS .Bl -tag -width Ds .It Fl m @@ -75,11 +75,10 @@ Print the location of the bottom side of the cropping rectangle in pixels. .It %f Print the filename of the image. Warning: This is printed out as is, without any escaping. -Yes, this should be fixed. .El .Pp If an unknown substitution is encountered, a warning is printed to -stderr and the characters are printed out verbatim. +standard error and the characters are printed out verbatim. .Sh KEYBINDS .Bl -tag -width Ds .It ARROW LEFT @@ -88,6 +87,11 @@ Go to the last image. Go to the next image. .It RETURN Go to the next image, copying the current cropping rectangle. +Note that this copies the visual rectangle, not the scaled rectangle +that is printed for the cropping command. +In other words, when switching to an image that is a different size and +thus scaled differently, the displayed rectangle will stay the same even +though the pixels covered in the original image are different. .It TAB Switch the color of the cropping rectangle between the primary and secondary colors. .It DELETE @@ -101,9 +105,10 @@ This is useful when automatic redrawing is disabled with .Bl -tag -width Ds .It LEFT-CLICK When inside an existing cropping rectangle, drag it around. -When on one of the edges, resize the rectangle, locking it to that dimension. -When on one of the corners, resize the rectangle regardless of dimension. -When outside an existing cropping rectangle, start a new cropping rectangle. +When on one of the edges, resize the rectangle, locking it to that axis. +When on one of the corners, resize the rectangle regardless of axis. +When outside an existing cropping rectangle, replace the current rectangle +with a new one. .El .Sh EXIT STATUS .Ex -std @@ -120,7 +125,7 @@ $ croptool *.jpg | sh .Ed .Pp It is also possible to do more advanced things. -For instance, to put cropped images into a separate directory instead of +For instance, to save cropped images into a separate directory instead of overwriting the original images, something like this can be done: .Bd -literal $ croptool -f "croptool_crop %wx%h+%l+%t '%f' '/path/to/cropped/%f'" *.jpg | sh diff --git a/croptool.c b/croptool.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 lumidify <nobody[at]lumidify.org> + * Copyright (c) 2021 lumidify <nobody@lumidify.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -137,7 +137,7 @@ static void cleanup(void); static void sort_coordinates(int *x0, int *y0, int *x1, int *y1); static void swap(int *a, int *b); static void redraw(void); -static void print_cmd(const char *filename, int x, int y, int w, int h); +static void print_cmd(const char *filename, int x, int y, int w, int h, int dry_run); static void print_selection(struct Selection *sel, const char *filename); static int collide_point(int x, int y, int x_point, int y_point); static int collide_line(int x, int y, int x0, int y0, int x1, int y1); @@ -207,6 +207,8 @@ main(int argc, char *argv[]) { break; } } + /* print warning if command format is invalid */ + print_cmd("", 0, 0, 0, 0, 1); argc -= optind; argv += optind; @@ -436,10 +438,11 @@ cleanup(void) { XCloseDisplay(state.dpy); } -/* TODO: Allow printing filename without ending */ -/* TODO: Escape filename properly */ +/* TODO: Escape filename properly + * -> But how? Since the format can be set by the user, + * it isn't really clear *what* needs to be escaped. */ static void -print_cmd(const char *filename, int x, int y, int w, int h) { +print_cmd(const char *filename, int x, int y, int w, int h, int dry_run) { short percent = 0; const char *c; int length = 0; @@ -449,49 +452,63 @@ print_cmd(const char *filename, int x, int y, int w, int h) { start_index++; if (*c == '%') { if (length) { - printf("%.*s", length, CMD_FORMAT + start_index); + if (!dry_run) + printf("%.*s", length, CMD_FORMAT + start_index); start_index += length; length = 0; } - if (percent) + if (percent && !dry_run) printf("%%"); percent++; percent %= 2; start_index++; } else if (percent && *c == 'w') { - printf("%d", w); + if (!dry_run) + printf("%d", w); percent = 0; } else if (percent && *c == 'h') { - printf("%d", h); + if (!dry_run) + printf("%d", h); percent = 0; } else if (percent && *c == 'l') { - printf("%d", x); + if (!dry_run) + printf("%d", x); percent = 0; } else if (percent && *c == 't') { - printf("%d", y); + if (!dry_run) + printf("%d", y); percent = 0; } else if (percent && *c == 'r') { - printf("%d", x + w); + if (!dry_run) + printf("%d", x + w); percent = 0; } else if (percent && *c == 'b') { - printf("%d", y + h); + if (!dry_run) + printf("%d", y + h); percent = 0; } else if (percent && *c == 'f') { - printf("%s", filename); + if (!dry_run) + printf("%s", filename); percent = 0; } else if (percent) { - fprintf(stderr, - "Warning: Unknown substitution '%c' in format string.\n", *c - ); - printf("%%%c", *c); + if (dry_run) { + fprintf(stderr, + "Warning: Unknown substitution '%c' " + "in format string.\n", *c + ); + } else { + printf("%%%c", *c); + } percent = 0; } else { length++; } } - if (length) - printf("%.*s", length, CMD_FORMAT + start_index); - printf("\n"); + if (!dry_run) { + if (length) + printf("%.*s", length, CMD_FORMAT + start_index); + printf("\n"); + } } /* Parses integer between 0 and 100 (non-inclusive). @@ -643,7 +660,7 @@ print_selection(struct Selection *sel, const char *filename) { y0 = y0 < 0 ? 0 : y0; x1 = x1 > sel->orig_w ? sel->orig_w : x1; y1 = y1 > sel->orig_h ? sel->orig_h : y1; - print_cmd(filename, x0, y0, x1 - x0, y1 - y0); + print_cmd(filename, x0, y0, x1 - x0, y1 - y0, 0); } static int diff --git a/croptool_crop.1 b/croptool_crop.1 @@ -17,7 +17,7 @@ to the dimensions specified, where .Ar width and .Ar height -are the width and height of the cropping rectangle, and +are the width and height of the cropping rectangle and .Ar x and .Ar y diff --git a/croptool_crop.c b/croptool_crop.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 lumidify <nobody[at]lumidify.org> + * Copyright (c) 2021 lumidify <nobody@lumidify.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above