A ascii/ascii.go => ascii/ascii.go +47 -0
@@ 0,0 1,47 @@
+// The ascii package 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 (
+ "image/color"
+ "math"
+ "reflect"
+)
+
+// Convert a pixel to a ASCII char string
+func ConvertPixelToASCII(pixel color.Color, options *Options) string {
+ defaultOptions := NewOptions()
+ defaultOptions.mergeOptions(options)
+
+ if defaultOptions.reverse {
+ defaultOptions.pixels = reverse(defaultOptions.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(options.pixels) - 1))
+ rawChar := options.pixels[roundValue(float64(value)/precision)]
+ 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
+}
A ascii/option.go => ascii/option.go +33 -0
@@ 0,0 1,33 @@
+package ascii
+
+// Convert options
+type Options struct {
+ pixels []byte
+ reverse bool
+ colored bool
+ bg bool
+ fg bool
+}
+
+// Default options
+var DefaultOptions = Options{
+ pixels: []byte(" .,:;i1tfLCG08@"),
+ reverse: false,
+ colored: true,
+ bg: false,
+ fg: true,
+}
+
+// Create a new options
+func NewOptions() Options {
+ return DefaultOptions
+}
+
+// Merge options
+func (options *Options) mergeOptions(newOptions *Options) {
+ options.pixels = append([]byte{}, newOptions.pixels...)
+ options.reverse = newOptions.reverse
+ options.colored = newOptions.colored
+ options.bg = newOptions.bg
+ options.fg = newOptions.fg
+}