~dricottone/image2ascii

ref: 32c6345ebc23b02d145076b1ac7ec2f1e4c2fc3a image2ascii/ascii/ascii.go -rw-r--r-- 1.6 KiB
32c6345e — qeesung add reverse options 6 years ago
                                                                                
49547468 qeesung
5f88c33e qeesung
c5de7795 qeesung
5f88c33e qeesung
49547468 qeesung
5f88c33e qeesung
32c6345e qeesung
5f88c33e qeesung
32c6345e qeesung
5f88c33e qeesung
32c6345e qeesung
c5de7795 qeesung
5f88c33e qeesung
c5de7795 qeesung
49547468 qeesung
c5de7795 qeesung
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
// Package ascii can convert a image pixel to a raw char
// base on it's RGBA value, in another word, input a image pixel
// output a raw char ascii.
package ascii

import (
	"github.com/aybabtme/rgbterm"
	"image/color"
	"math"
	"reflect"
)

// ConvertPixelToASCII converts a pixel to a ASCII char string
func ConvertPixelToASCII(pixel color.Color, options *Options) string {
	convertOptions := NewOptions()
	convertOptions.mergeOptions(options)

	if convertOptions.Reversed {
		convertOptions.Pixels = reverse(convertOptions.Pixels)
	}

	r := reflect.ValueOf(pixel).FieldByName("R").Uint()
	g := reflect.ValueOf(pixel).FieldByName("G").Uint()
	b := reflect.ValueOf(pixel).FieldByName("B").Uint()
	a := reflect.ValueOf(pixel).FieldByName("A").Uint()
	value := intensity(r, g, b, a)

	// Choose the char
	precision := float64(255 * 3 / (len(convertOptions.Pixels) - 1))
	rawChar := convertOptions.Pixels[roundValue(float64(value)/precision)]
	if convertOptions.Colored {
		return decorateWithColor(r, g, b, rawChar)
	}
	return string([]byte{rawChar})
}

func roundValue(value float64) int {
	return int(math.Floor(value + 0.5))
}

func reverse(numbers []byte) []byte {
	for i := 0; i < len(numbers)/2; i++ {
		j := len(numbers) - i - 1
		numbers[i], numbers[j] = numbers[j], numbers[i]
	}
	return numbers
}

func intensity(r, g, b, a uint64) uint64 {
	return (r + g + b) * a / 255
}

// decorateWithColor decorate the raw char with the color base on r,g,b value
func decorateWithColor(r, g, b uint64, rawChar byte) string {
	coloredChar := rgbterm.FgString(string([]byte{rawChar}), uint8(r), uint8(g), uint8(b))
	return coloredChar
}