textPixel

Display images in terminal
git clone https://noulin.net/git/textPixel.git
Log | Files | Refs | README

commit db2b11b9e8966b5afccbd9a7503525c5ef999f45
Author: Remy Noulin <loader2x@gmail.com>
Date:   Sat,  3 Oct 2020 21:03:25 +0200

display RGB images in terminal

README.md   |  22 +++++++++++
package.yml |  40 +++++++++++++++++++
textPixel.c | 127 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 189 insertions(+)

Diffstat:
AREADME.md | 22++++++++++++++++++++++
Apackage.yml | 40++++++++++++++++++++++++++++++++++++++++
AtextPixel.c | 127+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 189 insertions(+), 0 deletions(-)

diff --git a/README.md b/README.md @@ -0,0 +1,22 @@ +# Sheepy +This is a sheepy package for [sheepy](https://spartatek.se/r/sheepy/file/README.md.html) and using [libsheepy](https://spartatek.se/r/libsheepy/file/README.md.html) + +# textPixel + +textPixel displays images in RGB in the terminal with 2 pixel lines per character line using unicode character 0x2584 (half plain rectangle). + +textPixel depends on: +- ImageMagick (recent version) +- Terminal supporting RGB colors and unicode + +# Usage + +Install with spm: `spm -g install textPixel` + +Display images: +``` +# display image to terminal width: +textPixel pathToImage +# display image with 40 pixel/character width +textPixel pathToImage -w 40 +``` diff --git a/package.yml b/package.yml @@ -0,0 +1,40 @@ +--- + name: textPixel + version: 0.0.1 + description: "display images in terminal" + bin: ./textPixel.c + #cflags: -DA -g3 -std=gnu11 -fPIC -pipe + #lflags: -lpcre + repository: + type: git + url: git+https://noulin.net/git/textPixel.git + keywords: + #- utility + - command + - images + - terminal + - graphics + author: Remy + license: MIT + bugs: + url: https://noulin.net/git/textPixel/issues + homepage: https://noulin.net/textPixel/file/README.md.html + #compileHelp: # text displayed when there is a compilation error + #dependencies: + # md4c: + # Test configuration: + #testBin: ./testTextPixel.c + #testCflags: -g3 -std=gnu11 -fPIC -pipe -fprofile-arcs -ftest-coverage -Wall -Wextra + #testLflags: -lcheck_pic -lrt -lm -lsubunit -fprofile-arcs -ftest-coverage -rdynamic + # Memcheck configuration (sheepy -m): + #memcheckBin: ./memcheckTextPixel.c + #memcheckCmd: valgrind --leak-check=full --show-leak-kinds=all --error-exitcode=1 + #memcheckCflags: -g3 -std=gnu11 -fPIC -pipe + #memcheckLflags: -rdynamic + # The asan* are the options for building the libsasan tests (sheepy -a): + #asanBin: ./asanTextPixel.c + #asanCmd: env ASAN_OPTIONS="detect_leaks=1:detect_stack_use_after_return=1:halt_on_error=0:log_path=stdout:color=always:print_cmdline=1" + #asanCflags: -fsanitize=address -fno-omit-frame-pointer -fsanitize-recover=address # these flags are overriden by package.yml + #asanLflags: -rdynamic -fsanitize=address -lasan # these flags are overriden by package.yml + #documentationCmd: # command for generating the documentation with spm doc + private: false # true for private package diff --git a/textPixel.c b/textPixel.c @@ -0,0 +1,127 @@ +#! /usr/bin/env sheepy +/* or direct path to sheepy: #! /usr/local/bin/sheepy */ + +/* Libsheepy documentation: https://spartatek.se/libsheepy/ */ +#include "libsheepyObject.h" + +int argc; char **argv; + +/* enable/disable logging */ +/* #undef pLog */ +/* #define pLog(...) */ + +typ struct {u16 rows; u16 cols;} winSizet; +winSizet wsize (void); +u32 text2Color(char *s); + +int main(int ARGC, char** ARGV) { + + argc = ARGC; argv = ARGV; + + initLibsheepy(ARGV[0]); + setLogMode(LOG_FUNC); + //openProgLogFile(); + //setLogSymbols(LOG_UTF8); + //disableLibsheepyErrorLogs; + + if (argc < 2) { + logE("Image name missing."); + logI("Usage: textPixel imagePath [-w width]\nwidth must be a positive integer."); + XFAILURE; + } + + if (not isPath(argv[1])) { + logE("File not found '%s'.", argv[1]); + logI("Usage: textPixel imagePath [-w width]\nwidth must be a positive integer."); + XFAILURE; + } + + i32 width = 0; + + if (argc > 2) { + if (argc != 4) { + logE("Usage: textPixel imagePath [-w width]\nwidth must be a positive integer."); + XFAILURE; + } + if (not eqG(argv[2], "-w")) { + logE("Usage: textPixel imagePath [-w width]\nwidth must be a positive integer."); + XFAILURE; + } + width = parseInt(argv[3]); + if (not width) { + logE("Usage: textPixel imagePath [-w width]\nwidth must be a positive integer."); + XFAILURE; + } + } + + // find terminal size + winSizet sz = wsize(); // window cols + + if (not width) width = sz.cols; + + var r = execOutf("convert %s -resize %d txt:-", argv[1], width); + //logG(r); + + // r is a list of pixels like this: + // 99,132: (22616,22616,22616) #585858 srgb(88,88,88) + + rune rectangle = 0x2584; + char rect[6] = init0Var; + bRune2CodeUTF8(rect, rectangle); + //printf("%K%k%s"RST, 0xFFFFFF, 0x99BBFF, rect); // print unicode character for 2 pixels + + + // delete first line (not a pixel) + delElemG(&r, 0); + + u64 count = 0; + u64 line = 0; + bool skip100 = no; + var len = lenG(r); + // loop on pixels + forEachS(r, s) { + if (not skip100) { + #define bottomPixel (count+ line*(width*2) +width) + if (bottomPixel >= len) break; + u32 colorUp = text2Color(s); + u32 colorDown = text2Color(r[bottomPixel]); + printf("%K%k%s"RST, colorUp, colorDown, rect); + } + count++; + if (count == width) { + if (not skip100) { + //printf("$"); // end of line + put; + line++; + } + count = 0; + skip100 = skip100 ? no : yes; + } + } // pixel loop +} + +u32 text2Color(char *s) { + char *color = findG(s, "#")-1; + color[0] = '0'; + color[1] = 'x'; + char *end = findG(color, " "); + *end = 0; + //logVarG(color); + u32 r = parseHex(color); + //printf("%x\n",hexColor); + ret r; +} + +/* terminal window size */ +#include <sys/ioctl.h> +#include <unistd.h> + +winSizet wsize (void) +{ + struct winsize w; + ioctl(STDOUT_FILENO, TIOCGWINSZ, &w); + + return (winSizet){w.ws_row, w.ws_col}; +} + +// vim: set expandtab ts=2 sw=2: