Created
August 18, 2012 22:50
-
-
Save Cairnarvon/3390247 to your computer and use it in GitHub Desktop.
imgcat, a cat in an image^W^W^Wfor images
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
$ wget -q http://www.secretareaofvipquality.net/maiddog.png | |
$ ./imgcat maiddog.png | |
▟████▙██▄█▟▄██▜▙ | |
▞▜▙███▄▄▄▄▟██▜▞▚▄ | |
▄████████████████▛▘ | |
▝▀▀▘ ▖▖███▛▘▄▙▄▞▜██████▀▌ | |
▐██▌ ▖▜██▛██████▌ ▀▜██▙▝█▚ | |
▗▄▄▖ ▙▟█▌▟▀███▀▀▜█▛▄▟█████▙ | |
▗▜██▙█▟████████████████▙ | |
▗▄███▛▀▜█████████████████▌ | |
▗▄█████▖ ██████████████████ | |
▖▗ ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▜▚▟▀██▄ ▀▀▀▙████████████▌ | |
▖ ▗▄▖ ▀█████████████████▘ ▀▀▀▘ ▝▀▀▜█▟████████▖ | |
▗▄▄▖ ▝ ▗ ▝▀████████████▘ ▝████████████▘ | |
▗▄▄▄▄▟▙▟ ▞▘ ▀█████████▛ ▜▙████████████▜▌▘ | |
▗▄███▛██▙▙▖ ▝▀██████▌ ▝▀▀▀▜████▛▀█ ▄▄▄▖ | |
▟████████████▄ ▝▀▜██▙ ▚▖ ▄▛ ▄▀██▄▄ | |
███▟█████████████▄▖ ▝▀█▖ ▐██▙▄▄▄▄▄▛▘ ▟██▙▄███▄▖ | |
███████████████████▙▖ █▌ ▐███████▛ ▝▀████▙▟█▙▄▄ | |
▙▟██████████▛▜███████▙▖ ▝▘ ▄▄▖ ▟██▛███▀ ▘▜████▄██▙▄▄▖ | |
▜▛█████████▚▗██████████ ▗▟███████▛ ▜▘▗▄▖ ▗▖ ▝▜█████▟▛▙▟ | |
▌▗▖▝▀▘▀▀▛▀▗▐████████████▖ ▝ ▜█████████▄█▀▀▛▘ ▘ ▀ ▗ ▜█████▙▟ | |
▄▄▄▄██████▀ ██████▄▖ ▗ ▄▄ ▄ ▀▀███████▄█▌ ▗▖▞▀ | |
▄▄██████▙▞▘▝▀ ▀▜█▛▚ ▄▄▄▟▄▟▀▗ ▄▜███████▘ ▝▀▘ ▀▀▀ | |
▀▀▝ ▀███ ▘▖ ▝▀▀ ▀▀▀▀▀██▙ ▐▟███████▌ ▝▀▀▘ | |
▀▀▌ ▖ ▀▛▚ ▐█▛ ▗▄▗▄▖ ▀▀▀▀▀██▙ ▝▘▘▝▀▀▜▀▟▘ | |
▗▄ ▀▟██▌▝ ▝ ▝ ▀▚▄▄▄▗ |
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 <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-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-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-n\n" | |
"\t\tNormalise image.\n" | |
"\n" | |
"\t-i\n" | |
"\t\tInvert colours.\n" | |
"\n", | |
argv_0); | |
exit(1); | |
} | |
int main(int argc, char **argv) | |
{ | |
int width = 0, height = 0, normalise = 0, invert = 0; | |
char *shades[] = {" ", "▘", "▝", "▀", "▖", "▌", "▞", "▛", | |
"▗", "▚", "▐", "▜", "▄", "▙", "▟", "█"}; | |
/* Parse options. */ | |
int c; | |
extern int optind; | |
extern char *optarg; | |
while ((c = getopt(argc, argv, "+w:h:ni")) != -1) { | |
switch (c) { | |
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 '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 'n': | |
normalise = 1; | |
break; | |
case 'i': | |
invert = 1; | |
break; | |
default: | |
usage(argv[0]); | |
} | |
} | |
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); | |
width *= 2; | |
height *= 2; | |
if (!height) { | |
if (!width) | |
width = 160; | |
height = h * width / w / 2; | |
} | |
if (!width) | |
width = w * height * 2 / h; | |
if (width & 1) ++width; | |
if (height & 1) ++height; | |
MagickResizeImage(m_wand, width, height, LanczosFilter, 1.0); | |
if (normalise) { | |
MagickSetImageType(m_wand, GrayscaleType); | |
MagickNormalizeImage(m_wand); | |
} | |
if (invert) | |
MagickNegateImage(m_wand, MagickFalse); | |
/* Output. */ | |
for (int i = 0; i < height; i += 2) { | |
for (int j = 0; j < width; j += 2) { | |
PixelWand *p_wand = NewPixelWand(); | |
double h, s, l; | |
int p = 0; | |
MagickGetImagePixelColor(m_wand, j, i, p_wand); | |
PixelGetHSL(p_wand, &h, &s, &l); | |
if (l > 0.5) | |
p |= 1; | |
MagickGetImagePixelColor(m_wand, j + 1, i, p_wand); | |
PixelGetHSL(p_wand, &h, &s, &l); | |
if (l > 0.5) | |
p |= 2; | |
MagickGetImagePixelColor(m_wand, j, i + 1, p_wand); | |
PixelGetHSL(p_wand, &h, &s, &l); | |
if (l > 0.5) | |
p |= 4; | |
MagickGetImagePixelColor(m_wand, j + 1, i + 1, p_wand); | |
PixelGetHSL(p_wand, &h, &s, &l); | |
if (l > 0.5) | |
p |= 8; | |
printf("%s", shades[p]); | |
DestroyPixelWand(p_wand); | |
} | |
puts(""); | |
} | |
return 0; | |
} |
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
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