Skip to content

Commit

Permalink
Merge pull request #52 from mdesantis/preserve-aspect-ratio
Browse files Browse the repository at this point in the history
Preserve aspect ratio during resizing when the user provides both width and height
  • Loading branch information
eddieantonio committed Dec 18, 2023
2 parents 165df87 + 735920c commit 2bd6f64
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 14 deletions.
9 changes: 6 additions & 3 deletions docs/imgcat.1
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.\" Automatically generated by Pandoc 2.9.2.1
.\"
.TH "IMGCAT" "1" "October 31, 2023" "imgcat User Manual" "meow"
.TH "IMGCAT" "1" "December 10, 2023" "imgcat User Manual" "meow"
.hy
.SH NAME
.PP
Expand All @@ -26,8 +26,8 @@ This can be overridden using \f[B]-w\f[R] to adjust the maximum width or
the terminal; and \f[B]-d\f[R] to explicitly set the color depth.
You may also use \f[B]-r\f[R] to adjust the height (\[lq]r\[rq] for
\[lq]number of rows\[rq]).
If only one of \f[B]-w\f[R] or \f[B]-r\f[R] is provided, the image will
be scaled without affecting the aspect ratio, if possible.
The image will be scaled without affecting the aspect ratio, unless
\f[B]-P\f[R] is provided.
.PP
Setting \f[B]-H\f[R] enables the use of half-height block drawing
characters (as opposed to \[lq]full height\[rq] spaces used in the
Expand Down Expand Up @@ -76,6 +76,9 @@ Does nothing if \f[B]\[en]no-resize\f[R] is provided.
Maintains the original image\[cq]s aspect ratio if \f[B]\[en]width\f[R]
is NOT provided.
.TP
\f[B]-P\f[R], \f[B]\[en]no-preserve-aspect-ratio\f[R]
Does not preserve aspect ratio during image resizing.
.TP
\f[B]-R\f[R], \f[B]\[en]no-resize\f[R]
Does not resize the image to fit the terminal\[cq]s width.
Overrides both \f[B]\[en]width\f[R] and \f[B]\[en]height\f[R].
Expand Down
7 changes: 5 additions & 2 deletions docs/imgcat.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ detected for your terminal. This can be overridden using **-w** to
adjust the maximum width or **-R** to prevent resizing, even if the
image is too big to fit in the terminal; and **-d** to explicitly set
the color depth. You may also use **-r** to adjust the height ("r" for
"number of rows"). If only one of **-w** or **-r** is provided, the
image will be scaled without affecting the aspect ratio, if possible.
"number of rows"). The image will be scaled without affecting the aspect
ratio, unless **-P** is provided.

Setting **-H** enables the use of half-height block drawing characters
(as opposed to "full height" spaces used in the default mode). This
Expand Down Expand Up @@ -69,6 +69,9 @@ you're having a problem with this.
Does nothing if **--no-resize** is provided. Maintains the original image's
aspect ratio if **--width** is NOT provided.

**-P**, **--no-preserve-aspect-ratio**
~ Does not preserve aspect ratio during image resizing.

**-R**, **--no-resize**
~ Does not resize the image to fit the terminal's width. Overrides
both **--width** and **--height**.
Expand Down
24 changes: 16 additions & 8 deletions src/imgcat.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,15 @@ static struct {
int height;
bool use_half_height;
bool use_fake_terminal;
bool should_preserve_aspect_ratio;
} options = {
.format = F_UNSET, /* Default: autodetect highest fidelity. */
.should_resize = true, /* Default: yes! */
.width = WIDTH_UNSET,
.height = HEIGHT_UNSET,
.use_half_height = false,
.use_fake_terminal = false,
.should_preserve_aspect_ratio = true
};

/**
Expand All @@ -96,13 +98,14 @@ static char tempfile_name_template[NAME_MAX + 1];
/* Long options */
static struct option long_options[] = {
/* Options affecting output colour depth. */
{ "depth", required_argument, NULL, 'd' },
{ "depth", required_argument, NULL, 'd' },

/* Options affecting size. */
{ "no-resize", no_argument, NULL, 'R' },
{ "width", required_argument, NULL, 'w' },
{ "height", required_argument, NULL, 'r' },
{ "half-height", no_argument, NULL, 'H' },
{ "no-resize", no_argument, NULL, 'R' },
{ "width", required_argument, NULL, 'w' },
{ "height", required_argument, NULL, 'r' },
{ "half-height", no_argument, NULL, 'H' },
{ "no-preserve-aspect-ratio", no_argument, NULL, 'P' },

/* Abbreviated options. */
{ "8", no_argument, (int*) &options.format, F_8_COLOR },
Expand Down Expand Up @@ -198,7 +201,8 @@ int main(int argc, char **argv) {
.max_width = terminal->width,
.max_height = terminal->height,
.half_height = options.use_half_height,
.format = color_format
.format = color_format,
.preserve_aspect_ratio = options.should_preserve_aspect_ratio
};
status = print_image(&request);

Expand Down Expand Up @@ -324,7 +328,7 @@ static void usage(FILE *dest) {
const int field_width = strlen(program_name);
fprintf(dest, "Usage:\n");
fprintf(dest,
"\t%s" " [--width=<columns> --height=<rows>|--no-resize]\n"
"\t%s" " [--width=<columns> --height=<rows>|--no-resize] [--no-preserve-aspect-ratio]\n"
"\t%*c" " [--half-height] [--depth=(8|256|24bit|iterm2)] IMAGE\n",
program_name, field_width, ' ');
fprintf(dest, "\t"
Expand Down Expand Up @@ -385,7 +389,7 @@ static const char* parse_args(int argc, char **argv) {
opterr = 0;

while (1) {
c = getopt_long(argc, argv, "w:r:d:RHhv", long_options, NULL);
c = getopt_long(argc, argv, "w:r:d:PRHhv", long_options, NULL);
if (c == -1) {
break;
}
Expand Down Expand Up @@ -414,6 +418,10 @@ static const char* parse_args(int argc, char **argv) {
}
break;

case 'P': /* --no-preserve-aspect-ratio */
options.should_preserve_aspect_ratio = false;
break;

case 'R': /* --no-resize */
options.should_resize = false;
break;
Expand Down
26 changes: 25 additions & 1 deletion src/load_image.cc
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,29 @@ void maybe_resize(cimg_library::CImg<unsigned char>& img, const LoadOpts& option
/* Make sure the image is never smaller than 1x1 pixels. */
int new_width = std::max(options.desired_width, 1);
int new_height = std::max(options.desired_height, 1);

/* Resize preserving aspect ratio. */
if (options.preserve_aspect_ratio) {
int max_width = new_width;
int max_height = new_height;
new_width = img.width();
new_height = img.height();

if (new_width > max_width) {
new_width = max_width;
double ratio = ((double) img.height()) / img.width();
/* Scale height, ensuring it's at least 1px. */
new_height = std::max((int) (ratio * (double) new_width), 1);
}

if (new_height > max_height) {
new_height = max_height;
double ratio = ((double) img.width()) / img.height();
/* Scale width, ensuring it's at least 1px. */
new_width = std::max((int) (ratio * (double) new_height), 1);
}
}

img.resize(new_width, new_height);
} else if (resize_width) {
/* Only resize if the image is strictly greater than the source width. */
Expand All @@ -142,7 +165,8 @@ void maybe_resize(cimg_library::CImg<unsigned char>& img, const LoadOpts& option
}
int new_width = options.desired_width;
double ratio = ((double) img.height()) / img.width();
int new_height = ratio * (double) new_width;
/* Scale height, ensuring it's at least 1px. */
int new_height = std::max((int) (ratio * (double) new_width), 1);
img.resize(new_width, new_height);
} else if (resize_height) {
/* Resize without affecting aspect ratio. */
Expand Down
1 change: 1 addition & 0 deletions src/load_image.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ struct LoadOpts {
int max_height;
int desired_width;
int desired_height;
bool preserve_aspect_ratio;
};

/**
Expand Down
1 change: 1 addition & 0 deletions src/print_image.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ static bool print_iterate(PrintRequest *request) {
.max_height = request->max_height,
.desired_width = request->desired_width,
.desired_height = request->desired_height,
.preserve_aspect_ratio = request->preserve_aspect_ratio,
};
assert(format != F_UNSET);

Expand Down
1 change: 1 addition & 0 deletions src/print_image.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ typedef struct {
int desired_width;
int desired_height;
bool half_height;
bool preserve_aspect_ratio;
Format format;
} PrintRequest;

Expand Down

0 comments on commit 2bd6f64

Please sign in to comment.