Skip to content

Instantly share code, notes, and snippets.

@jorrizza
Created May 21, 2014 09:43
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jorrizza/e9deadd9fd1318ee09fb to your computer and use it in GitHub Desktop.
Save jorrizza/e9deadd9fd1318ee09fb to your computer and use it in GitHub Desktop.
Show an image in the terminal
package main
import (
"fmt"
"github.com/nfnt/resize"
"image"
"image/color"
_ "image/gif"
_ "image/jpeg"
_ "image/png"
"log"
"math"
"os"
"syscall"
"unsafe"
)
func terminalSize() (w, h int, err error) {
var sizes [4]uint16
_, _, errno := syscall.Syscall6(syscall.SYS_IOCTL, 1, uintptr(syscall.TIOCGWINSZ), uintptr(unsafe.Pointer(&sizes)), 0, 0, 0)
if errno != 0 {
return -1, -1, errno
}
return int(sizes[1]), int(sizes[0]), nil
}
func distanceColor(ca, cb []uint32) float64 {
return math.Sqrt(math.Pow((float64(ca[0])-float64(cb[0])), 2) + math.Pow((float64(ca[1])-float64(cb[1])), 2) + math.Pow((float64(ca[2])-float64(cb[2])), 2))
}
func idxColor(clr color.Color) int {
var d, distance float64
var idx int = 0
ca := []uint32{0, 0, 0}
table := [][]uint32{
{0, 0, 0},
{32768, 0, 0},
{0, 32768, 0},
{32768, 32768, 0},
{0, 0, 32768},
{32768, 0, 32768},
{0, 32768, 32768},
{49152, 49152, 49152},
{32768, 32768, 32768},
{65280, 0, 0},
{0, 65280, 0},
{65280, 65280, 0},
{0, 0, 65280},
{65280, 0, 65280},
{0, 65280, 65280},
{65280, 65280, 65280},
{0, 0, 0},
{0, 0, 24320},
{0, 0, 34560},
{0, 0, 44800},
{0, 0, 57088},
{0, 0, 65280},
{0, 24320, 0},
{0, 24320, 24320},
{0, 24320, 34560},
{0, 24320, 44800},
{0, 24320, 57088},
{0, 24320, 65280},
{0, 34560, 0},
{0, 34560, 24320},
{0, 34560, 34560},
{0, 34560, 44800},
{0, 34560, 57088},
{0, 34560, 65280},
{0, 44800, 0},
{0, 44800, 24320},
{0, 44800, 34560},
{0, 44800, 44800},
{0, 44800, 57088},
{0, 44800, 65280},
{0, 57088, 0},
{0, 57088, 24320},
{0, 57088, 34560},
{0, 57088, 44800},
{0, 57088, 57088},
{0, 57088, 65280},
{0, 65280, 0},
{0, 65280, 24320},
{0, 65280, 34560},
{0, 65280, 44800},
{0, 65280, 57088},
{0, 65280, 65280},
{24320, 0, 0},
{24320, 0, 24320},
{24320, 0, 34560},
{24320, 0, 44800},
{24320, 0, 57088},
{24320, 0, 65280},
{24320, 24320, 0},
{24320, 24320, 24320},
{24320, 24320, 34560},
{24320, 24320, 44800},
{24320, 24320, 57088},
{24320, 24320, 65280},
{24320, 34560, 0},
{24320, 34560, 24320},
{24320, 34560, 34560},
{24320, 34560, 44800},
{24320, 34560, 57088},
{24320, 34560, 65280},
{24320, 44800, 0},
{24320, 44800, 24320},
{24320, 44800, 34560},
{24320, 44800, 44800},
{24320, 44800, 57088},
{24320, 44800, 65280},
{24320, 57088, 0},
{24320, 57088, 24320},
{24320, 57088, 34560},
{24320, 57088, 44800},
{24320, 57088, 57088},
{24320, 57088, 65280},
{24320, 65280, 0},
{24320, 65280, 24320},
{24320, 65280, 34560},
{24320, 65280, 44800},
{24320, 65280, 57088},
{24320, 65280, 65280},
{34560, 0, 0},
{34560, 0, 24320},
{34560, 0, 34560},
{34560, 0, 44800},
{34560, 0, 57088},
{34560, 0, 65280},
{34560, 24320, 0},
{34560, 24320, 24320},
{34560, 24320, 34560},
{34560, 24320, 44800},
{34560, 24320, 57088},
{34560, 24320, 65280},
{34560, 34560, 0},
{34560, 34560, 24320},
{34560, 34560, 34560},
{34560, 34560, 44800},
{34560, 34560, 57088},
{34560, 34560, 65280},
{34560, 44800, 0},
{34560, 44800, 24320},
{34560, 44800, 34560},
{34560, 44800, 44800},
{34560, 44800, 57088},
{34560, 44800, 65280},
{34560, 57088, 0},
{34560, 57088, 24320},
{34560, 57088, 34560},
{34560, 57088, 44800},
{34560, 57088, 57088},
{34560, 57088, 65280},
{34560, 65280, 0},
{34560, 65280, 24320},
{34560, 65280, 34560},
{34560, 65280, 44800},
{34560, 65280, 57088},
{34560, 65280, 65280},
{44800, 0, 0},
{44800, 0, 24320},
{44800, 0, 34560},
{44800, 0, 44800},
{44800, 0, 57088},
{44800, 0, 65280},
{44800, 24320, 0},
{44800, 24320, 24320},
{44800, 24320, 34560},
{44800, 24320, 44800},
{44800, 24320, 57088},
{44800, 24320, 65280},
{44800, 34560, 0},
{44800, 34560, 24320},
{44800, 34560, 34560},
{44800, 34560, 44800},
{44800, 34560, 57088},
{44800, 34560, 65280},
{44800, 44800, 0},
{44800, 44800, 24320},
{44800, 44800, 34560},
{44800, 44800, 44800},
{44800, 44800, 57088},
{44800, 44800, 65280},
{44800, 57088, 0},
{44800, 57088, 24320},
{44800, 57088, 34560},
{44800, 57088, 44800},
{44800, 57088, 57088},
{44800, 57088, 65280},
{44800, 65280, 0},
{44800, 65280, 24320},
{44800, 65280, 34560},
{44800, 65280, 44800},
{44800, 65280, 57088},
{44800, 65280, 65280},
{57088, 0, 0},
{57088, 0, 24320},
{57088, 0, 34560},
{57088, 0, 44800},
{57088, 0, 57088},
{57088, 0, 65280},
{57088, 24320, 0},
{57088, 24320, 24320},
{57088, 24320, 34560},
{57088, 24320, 44800},
{57088, 24320, 57088},
{57088, 24320, 65280},
{57088, 34560, 0},
{57088, 34560, 24320},
{57088, 34560, 34560},
{57088, 34560, 44800},
{57088, 34560, 57088},
{57088, 34560, 65280},
{57088, 44800, 0},
{57088, 44800, 24320},
{57088, 44800, 34560},
{57088, 44800, 44800},
{57088, 44800, 57088},
{57088, 44800, 65280},
{57088, 57088, 0},
{57088, 57088, 24320},
{57088, 57088, 34560},
{57088, 57088, 44800},
{57088, 57088, 57088},
{57088, 57088, 65280},
{57088, 65280, 0},
{57088, 65280, 24320},
{57088, 65280, 34560},
{57088, 65280, 44800},
{57088, 65280, 57088},
{57088, 65280, 65280},
{65280, 0, 0},
{65280, 0, 24320},
{65280, 0, 34560},
{65280, 0, 44800},
{65280, 0, 57088},
{65280, 0, 65280},
{65280, 24320, 0},
{65280, 24320, 24320},
{65280, 24320, 34560},
{65280, 24320, 44800},
{65280, 24320, 57088},
{65280, 24320, 65280},
{65280, 34560, 0},
{65280, 34560, 24320},
{65280, 34560, 34560},
{65280, 34560, 44800},
{65280, 34560, 57088},
{65280, 34560, 65280},
{65280, 44800, 0},
{65280, 44800, 24320},
{65280, 44800, 34560},
{65280, 44800, 44800},
{65280, 44800, 57088},
{65280, 44800, 65280},
{65280, 57088, 0},
{65280, 57088, 24320},
{65280, 57088, 34560},
{65280, 57088, 44800},
{65280, 57088, 57088},
{65280, 57088, 65280},
{65280, 65280, 0},
{65280, 65280, 24320},
{65280, 65280, 34560},
{65280, 65280, 44800},
{65280, 65280, 57088},
{65280, 65280, 65280},
{2048, 2048, 2048},
{4608, 4608, 4608},
{7168, 7168, 7168},
{9728, 9728, 9728},
{12288, 12288, 12288},
{14848, 14848, 14848},
{17408, 17408, 17408},
{19968, 19968, 19968},
{22528, 22528, 22528},
{24576, 24576, 24576},
{26112, 26112, 26112},
{30208, 30208, 30208},
{32768, 32768, 32768},
{35328, 35328, 35328},
{37888, 37888, 37888},
{40448, 40448, 40448},
{43008, 43008, 43008},
{45568, 45568, 45568},
{48128, 48128, 48128},
{50688, 50688, 50688},
{53248, 53248, 53248},
{55808, 55808, 55808},
{58368, 58368, 58368},
{60928, 60928, 60928},
}
r, g, b, _ := clr.RGBA()
ca[0] = r
ca[1] = g
ca[2] = b
for i, cb := range table {
if i < 16 {
// We skip the first 16, because those are user configured
} else if i == 16 {
distance = distanceColor(ca, cb)
idx = i
} else {
d = distanceColor(ca, cb)
if d < distance {
distance = d
idx = i
}
}
}
return idx
}
func imgCat(img image.Image) {
var idx1, idx2 int
bounds := img.Bounds()
for y := bounds.Min.Y; y < bounds.Max.Y; y += 2 {
for x := bounds.Min.X; x < bounds.Max.X; x++ {
idx1 = idxColor(img.At(x, y))
idx2 = idxColor(img.At(x, y+1))
fmt.Printf("\x1b[38;5;%dm\x1b[48;5;%dm▀\x1b[00m", idx1, idx2)
}
fmt.Println("")
}
}
func main() {
if len(os.Args) < 2 {
fmt.Printf("Usage: %s filename\n", os.Args[0])
os.Exit(2)
}
file, err := os.Open(os.Args[1])
if err != nil {
log.Fatal(err)
}
img, _, err := image.Decode(file)
if err != nil {
log.Fatal(err)
}
tw, th, err := terminalSize()
if err != nil {
log.Fatal(err)
}
imgResized := resize.Thumbnail(uint(tw), uint(th*2), img, resize.Lanczos3)
imgCat(imgResized)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment