Created
May 21, 2014 09:43
-
-
Save jorrizza/e9deadd9fd1318ee09fb to your computer and use it in GitHub Desktop.
Show an image in the terminal
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
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