sophuwu.site > sketch   
              108
            
             package main

import (
	"fmt"
	"github.com/nfnt/resize"
	"golang.org/x/term"
	"image"
	_ "image/jpeg"
	_ "image/png"
	"math"
	"os"
	"strings"
)

func getTermSize() (int, int) {
	W, H, err := term.GetSize(int(os.Stdout.Fd()))
	if err != nil || !(W > 0 && H > 0) {
		fmt.Fprintln(os.Stderr, "fatal: could not get terminal size")
		os.Exit(1)
	}
	return W, H
}

func (img *Immg) FitSize(W, H int) {
	y := float64(img.Img.Bounds().Dy())
	x := float64(img.Img.Bounds().Dx())
	w := float64(W)
	h := float64(H)*2 - 1
	if x > w {
		y = y * w / x
		x = w
	}
	if y > h {
		x = x * h / y
		y = h
	}
	img.Img = resize.Resize(uint(math.Round(x)), uint(math.Round(y)), img.Img, resize.MitchellNetravali)
}

func (img *Immg) OpenImg(path string) error {
	file, err := os.Open(path)
	if err != nil {
		return fmt.Errorf("error opening file: %s", path)
	}
	defer file.Close()
	img.Img, _, err = image.Decode(file)
	if err != nil {
		return fmt.Errorf("error decoding file: %s", path)
	}
	return nil
}

type Immg struct {
	Img image.Image
	X   int
	Y   int
}

func (img *Immg) ForX() {
	img.X = 0
	for img.X < 2*(img.Img.Bounds().Dx()) {
		img.Doalp()
		img.X++
		img.Doalp()
		img.X++
		fmt.Print("▀\033[0m")
	}
}

func (img *Immg) Print() {
	img.Y = img.Img.Bounds().Min.Y
	for img.Y < img.Img.Bounds().Max.Y {
		img.ForX()
		fmt.Println()
		img.Y += 2
	}
}

func (img *Immg) Doalp() {
	r, g, b, _ := img.Img.At(img.Img.Bounds().Min.X+img.X/2, img.Y+img.X%2).RGBA()
	fmt.Printf("\033[%d8;2;%d;%d;%dm", 3+(img.X%2), r>>8, g>>8, b>>8)
}

func main() {
	if len(os.Args) < 2 {
		fmt.Fprintln(os.Stderr, "fatal: no image specified")
		os.Exit(1)
	}
	W, H := getTermSize()
	var img Immg
	var err error
	for _, path := range os.Args[1:] {
		if strings.HasPrefix(path, "-") && len(path) == 2 && '1' <= path[1] && path[1] <= '9' {
			W *= (int(path[1]) - '0')
			W /= 10
			H *= (int(path[1]) - '0')
			H /= 10
			continue
		}
		err = img.OpenImg(path)
		if err != nil {
			fmt.Fprintf(os.Stderr, "error opening image: %s\n", path)
			continue
		}
		img.FitSize(W, H)
		img.Print()
	}
}