From 5f88c33e0a1e0f72ef640e0937def1d46076ceff Mon Sep 17 00:00:00 2001 From: qeesung <1245712564@qq.com> Date: Sat, 20 Oct 2018 18:44:29 +0800 Subject: [PATCH] add ascii package to convert a image pixel to ascii --- ascii/ascii.go | 47 +++++++++++++++++++++++++++++++++++++++++++++++ ascii/option.go | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 ascii/ascii.go create mode 100644 ascii/option.go diff --git a/ascii/ascii.go b/ascii/ascii.go new file mode 100644 index 0000000..bd97f55 --- /dev/null +++ b/ascii/ascii.go @@ -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 +} diff --git a/ascii/option.go b/ascii/option.go new file mode 100644 index 0000000..860526f --- /dev/null +++ b/ascii/option.go @@ -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 +} -- 2.45.2