Created
August 20, 2012 01:55
-
-
Save Cairnarvon/3399268 to your computer and use it in GitHub Desktop.
Variations on a theme.
This file contains 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
$ wget -q http://www.secretareaofvipquality.net/maiddog.png | |
$ ./imgcat maiddog.png | |
▓▒█▓█▓▓█▓█▓▓▓▒▒▒ | |
▒▒▓█▓▒░▓▓▓▒▒▓▒▒▒▒ | |
▓▓▒▓██████▓██▓▓░░░ | |
▓▓▓▓▓▒▒▒▒▒▒▒▓▓▓▓▓▓▓░ | |
▓▓▓ ▓▒▓▓▒█▓▓██▓▒▒▒▒▓▓▒▓▓▓ | |
▓▓▓ ▓▓▓▒▓░▓▓▓ ▒▓▒▒▒▓▓▓▓▓█ | |
█▓▓▓▒▓██████▓▓▓▓▓▓▓▓██▓▓ | |
▓██▓▓▒░░▓██▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ | |
█████ ▓▓█▓█▓▓█░▓▓▒ ░▒▒▓▒▓▓▒▒▒▒▒▓▓▓▓▓▓▓ | |
▒█░ ██▒░▒▒▒▒▒▒▒▒▒▒▒▓▒▒▒▓▒▒▓▓▓▓▒ | |
▒▒░ ▒█░░░▒▒▓▓████████████▓ ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓▓▓▓▓▒ | |
▒ █░ ░▒███████████ ▒▒▒▒▒▒▒▒▒▒▒▓▓▓▓▓▓▓▓▒ ░░░ | |
▒▒▓▓█▓ ░████████░ ▒▒▒▒▒▒▓▓▓▓▓▓▓▓▓░▒░▒ ░░░ | |
▓▒▓▒▓▒▓▓▓▓▓▒ ▒▓▓██▓▒ ░▒▒ ░░░░▒▒░ ▓░ █▓▒▒▒▒ | |
▒▓▓█▓▓▓▓▓▓▓▓▓▓▓▓▒ ▒▓█ ░▓▒▒░ ▒▓ ▒▓▓░▒▓▓▓▒▒▒▒ | |
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓░ ▓░ ░▓▓▓▓▒▒▒▒▒ ▒▒▓▓▓▓▓▒▓▓▒▒▒▒▒▒ | |
▓▓▓▓▓▓▓▓▓▓▓▒▒▓▓▓▓▓█▓▓▒ ▒▒ ░ ▓▒▒▒▒▒▓▓▒░░░░░▒▒▒▒▓██▓▒█▓▓▒▒▒ | |
░▒▓▓▓▓▓▓▓▓▓▒░▓████▓▓▓▓▓░ ▒▓████▓▒▒▒▒▒▒▒▒ █ ▓▓▓ ░░░▒▓▓▓██▓██▒▓ | |
▒▒▒▒▒▓▒▓▒▒ ▓▓▓▓▓▓▓▓▓▓▓▓▒░ ▒█▒▓▓▓▓████▓▓▓▓▓▓▒░█░░░░░░░ ░ ░▒▓▓▓▓▓▓▓▓ | |
▒▒▒ ░▒▓▓▓█▓▓▒░▓▓▓▓▓▓░█ ░░ █▒▒▒▓▓▓███▓█▒ ▒▒ ░░░▒ ░▒░░░░▒▓ | |
░░░░░░▒▒▓▓▓▓▓▒▓░▒▓▒░▒▓▓▓▒ ▒▒▒▒▒▒░▒ ░▓▓█▓▓▓▓▒▒ ▒▒░░▒ ▒▒▒ | |
▒▒▒▒░▒▓▓▓█░▒▒░▒░░░░▒▒▒ ▒▒▒▒▒▒▒▓░▒░▓▓▓██▓▓▒ ▒▒▒ | |
▒▒▒ ▒░▒▓▒▓▒▒▒▒ █▓ ▒▒▒▒▒▒▒▒ ░▒▒░▓▓▓▓▓▒ | |
▒▒▒ ▒▒▒▒▒▒░ ░ ▒▒▒▒ ▒▒▒ |
This file contains 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 <getopt.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <unistd.h> | |
#include <sys/ioctl.h> | |
#include <wand/magick_wand.h> | |
void usage(char *argv_0) { | |
fprintf( | |
stderr, | |
"Usage: %s [OPTIONS] FILENAME\n" | |
"\n" | |
"Options:\n" | |
"\t--width, -w N|auto\n" | |
"\t\tSpecify width of the output, or `auto' for terminal width.\n" | |
"\t\tPreserves aspect ratio if unspecified. Defaults to 80 if both\n" | |
"\t\t-w and -h are omitted.\n" | |
"\n" | |
"\t--height, -h N|auto\n" | |
"\t\tSpecify height of the output, or `auto' for terminal height.\n" | |
"\t\tPreserves aspect ratio if unspecified.\n" | |
"\n" | |
"\t--mode, -m no-white|monochrome\n" | |
"\t\tOutput control.\n" | |
"\t--normalise, -n\n" | |
"\t\tNormalise image.\n" | |
"\n" | |
"\t--invert, -i\n" | |
"\t\tInvert colours.\n" | |
"\n", | |
argv_0); | |
exit(1); | |
} | |
int main(int argc, char **argv) | |
{ | |
int width = 0, height = 0, mode = 0, normalise = 0, invert = 0; | |
char **shades; | |
char *sh[3][5] = { | |
{" ", "░", "▒", "▓", "█"}, | |
{"░", "▒", "▓", "█", "."}, | |
{" ", "█", ".", ".", "."} | |
}; | |
/* Parse options. */ | |
enum { NURUPO, WIDTH, HEIGHT, MODE, NORMALISE, INVERT }; | |
static struct option long_options[] = { | |
{"width", 1, NULL, WIDTH}, | |
{"height", 1, NULL, HEIGHT}, | |
{"mode", 1, NULL, MODE}, | |
{"normalise", 0, NULL, NORMALISE}, | |
{"invert", 0, NULL, INVERT}, | |
{0, 0, 0, NURUPO} | |
}; | |
int c = 0; | |
extern int optind; | |
while ((c = getopt_long(argc, argv, "w:h:m:ni", long_options, NULL)) != -1) { | |
switch (c) { | |
case WIDTH: | |
case 'w': | |
if (strcmp(optarg, "auto") == 0) { | |
struct winsize w; | |
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w); | |
width = w.ws_col; | |
} else | |
width = atoi(optarg); | |
if (width < 0) | |
usage(argv[0]); | |
break; | |
case HEIGHT: | |
case 'h': | |
if (strcmp(optarg, "auto") == 0) { | |
struct winsize w; | |
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w); | |
height = w.ws_row; | |
} else | |
height = atoi(optarg); | |
if (height < 0) | |
usage(argv[0]); | |
break; | |
case MODE: | |
case 'm': | |
if (strcmp(optarg, "no-white") == 0) | |
mode = 1; | |
else if (strncmp(optarg, "mono", 4) == 0) | |
mode = 2; | |
else | |
usage(argv[0]); | |
break; | |
case NORMALISE: | |
case 'n': | |
normalise = 1; | |
break; | |
case INVERT: | |
case 'i': | |
invert = 1; | |
break; | |
default: | |
usage(argv[0]); | |
} | |
} | |
shades = sh[mode]; | |
if (optind == argc) | |
usage(argv[0]); | |
/* Try to load image. */ | |
MagickWand *m_wand; | |
MagickWandGenesis(); | |
m_wand = NewMagickWand(); | |
if (MagickReadImage(m_wand, argv[optind]) == MagickFalse) { | |
perror("Can't into file"); | |
return 1; | |
} | |
/* Resize and optionally normalise and invert image. */ | |
size_t w = MagickGetImageWidth(m_wand), | |
h = MagickGetImageHeight(m_wand); | |
if (!height) { | |
if (!width) | |
width = 80; | |
height = h * width / w / 2; | |
} | |
if (!width) | |
width = w * height * 2 / h; | |
MagickResizeImage(m_wand, width, height, LanczosFilter, 0.5); | |
if (normalise) { | |
MagickSetImageType(m_wand, GrayscaleType); | |
MagickNormalizeImage(m_wand); | |
} | |
if (invert) | |
MagickNegateImage(m_wand, MagickFalse); | |
/* Output. */ | |
if (mode == 0) | |
mode = 5; | |
else if (mode == 1) | |
mode = 4; | |
else | |
mode = 2; | |
for (int i = 0; i < height; ++i) { | |
for (int j = 0; j < width; ++j) { | |
PixelWand *p_wand = NewPixelWand(); | |
double h, s, l; | |
int level; | |
MagickGetImagePixelColor(m_wand, j, i, p_wand); | |
PixelGetHSL(p_wand, &h, &s, &l); | |
level = (int)(l * mode); | |
if (level == mode) | |
--level; | |
printf("%s", shades[level]); | |
DestroyPixelWand(p_wand); | |
} | |
puts(""); | |
} | |
return 0; | |
} |
This file contains 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
MW = `MagickWand-config --cflags --ldflags --libs` | |
WARNS = -Wall -Wextra -pedantic -std=c99 | |
.PHONY: all | |
all: imgcat | |
imgcat: imgcat.c | |
$(CC) -o $@ $(MW) $(WARNS) $(CFLAGS) $^ | |
.PHONY: clean | |
clean: | |
rm -rf imgcat |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment