Skip to content

Commit

Permalink
Merge pull request #3 from msqtt/master
Browse files Browse the repository at this point in the history
Change a lot, added gif animation feature. :P
  • Loading branch information
msqtt authored May 6, 2023
2 parents 4c3b498 + 8d8da1c commit e827654
Show file tree
Hide file tree
Showing 12 changed files with 256 additions and 104 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.pprof
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ braille unicode.
| ![image](https://user-images.githubusercontent.com/94043894/223675190-ecbd20a6-cf49-40a0-a36d-d7bf6b0a75ff.png) |
| reverse when your background is too light. |

| ![image](https://user-images.githubusercontent.com/94043894/223677662-d27bc50a-3364-461f-bad4-ba7f0c4b8df9.png) |
| ![image](https://user-images.githubusercontent.com/94043894/236626257-7fb68cf0-89e7-4230-885f-f6f62b95490b.gif) |
| :-------------------------------------------------------------------------------------------------------------: |
| gif, not much use though. 💩 |

Expand All @@ -31,16 +31,16 @@ braille unicode.

### 🍰 How2use

`bobibo /path/to/image.png [-option]`
`bobibo [-option] /path/to/image.png `

options:

- `-r` enable reverse the character color.
- `-g` enable gif mode, print every frame of gif image.
- `-v` enable reverse the character color.
- `-g` enable gif mode(test), print every frame of gif image.
- `-s value` set the scale for images(value default 0.5, (0, +)).
- `-t value` set the threshold of binarization(value default generate by OTSU, [0, 255]).
- `-t value` set the threshold of binarization(value default generate by OTSU, [-1, 255]).

> use `bobibo help` to print options.
> use `bobibo -h` to print options.
> use `bobibo version` to print version.
### ⚙️ Contribute
Expand Down
85 changes: 67 additions & 18 deletions bobibo.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package bobibo

import (
"errors"
"io"

"github.com/orzation/bobibo/img"
Expand All @@ -10,54 +11,102 @@ import (
type Params struct {
Image io.Reader
Gif bool
Reverse bool
Inverse bool
Scale float64
Threshold int
}

type Option func(p *Params)
type Option func(p *Params) error

func BoBiBo(ima io.Reader, isGif, ifReverse bool, scale float64, threshold int, opts ...Option) (<-chan []string, error) {
func ScaleOpt(scale float64) Option {
return func(p *Params) error {
if scale <= 0 {
return errors.New("The Value of scale must be within (0, +).")
}
p.Scale = scale
return nil
}
}

func ThresholdOpt(thre int) Option {
return func(p *Params) error {
if thre < -1 || thre > 255 {
return errors.New("The Value of threshold must be within [-1, 255].")
}
p.Threshold = thre
return nil
}
}

type Art struct {
Content []string
Delay int
}

func BoBiBo(ima io.Reader, isGif, isInverse bool, opts ...Option) (<-chan Art, error) {
params := &Params{
Image: ima,
Gif: isGif,
Reverse: ifReverse,
Scale: scale,
Threshold: threshold,
Image: ima,
Gif: isGif,
Inverse: isInverse,
}
for _, opt := range opts {
opt(params)
if err := opt(params); err != nil {
return nil, err
}
}

inStream := make(chan img.Img)

mix := u.Multiply(img.ArtotBin(params.Reverse),
mix := u.Multiply(img.ArtotBin(params.Inverse),
u.Multiply(img.BinotImg(params.Threshold),
u.Multiply(img.TurnGray,
img.Resize(params.Scale))))
img.Resize(params.Scale),
)))

outStream := mix(inStream)
err := putStream(inStream, params)
delays, err := putStream(inStream, params)
wrap := wrapOut(delays)
if err != nil {
return nil, err
}
return outStream, nil
return wrap(outStream), nil
}

var wrapOut = func(delays []int) func(<-chan []string) <-chan Art {
flag := true
if delays == nil || len(delays) == 0 {
flag = false
}
return u.GenChanFunc(func(out <-chan []string, wrapOut chan<- Art) {
cnt := 0
for o := range out {
if flag {
wrapOut <- Art{Content: o, Delay: delays[cnt]}
} else {
wrapOut <- Art{Content: o, Delay: 0}
}
cnt++
}
})
}

func putStream(in chan<- img.Img, params *Params) error {
func putStream(in chan<- img.Img, params *Params) ([]int, error) {
var delays []int
if params.Gif {
p, err := img.LoadAGif(params.Image)
p, dls, err := img.LoadAGif(params.Image)
if err != nil {
return err
return nil, err
}
delays = dls
go inStream(in, p...)
} else {
i, err := img.LoadAImage(params.Image)
if err != nil {
return err
return nil, err
}
go inStream(in, i)
}
return nil
return delays, nil
}

func inStream[T img.Img](in chan<- img.Img, ims ...T) {
Expand Down
33 changes: 30 additions & 3 deletions bobibo_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,45 @@ import (
)

func TestBobibo(t *testing.T) {
f, err := os.Open("./test.jpg")
f, err := os.Open("./test.gif")
defer f.Close()
if err != nil {
t.Error(err)
}
c, err2 := BoBiBo(f, false, false, 1.0, -1)
c, err2 := BoBiBo(f, false, false, ScaleOpt(0.25), ThresholdOpt(-1))
if err2 != nil {
panic(err2)
}
for e := range c {
for _, v := range e {
for _, v := range e.Content {
fmt.Println(v)
}
}
}

func BenchmarkBobibo(b *testing.B) {
f, err := os.Open("./test.gif")
if err != nil {
b.Error(err)
}
defer f.Close()
b.ResetTimer()
for i := 0; i < b.N; i++ {
b.StopTimer()
f.Seek(0, 0)
b.StartTimer()
arts, err := BoBiBo(f, true, false, ScaleOpt(1), ThresholdOpt(-1))
if err != nil {
b.Error(err)
}
for {
select {
case _, ok := <-arts:
if !ok {
goto loopOut
}
}
}
loopOut:
}
}
104 changes: 42 additions & 62 deletions cli/cli.go
Original file line number Diff line number Diff line change
@@ -1,88 +1,68 @@
package main

import (
"flag"
"fmt"
"os"
"strconv"

"github.com/orzation/bobibo"
)

var (
version string

gif bool
inverse bool
scale float64
threshold int
)

func init() {
flag.BoolVar(&gif, "g", false, "enable gif mode.")
flag.BoolVar(&inverse, "v", false, "inverse the colors.")
flag.Float64Var(&scale, "s", 0.5, "scale the size of arts. range: (0, +).")
flag.IntVar(&threshold, "t", -1, "set the threshold of binarization. range: [-1, 255], -1 means gen by OTSU.")
}

func main() {
if len(os.Args) <= 1 {
fmt.Println("Please input a path of image.")
fmt.Println("Or using help to print options.")
fmt.Println("Or using version to print version.")
fmt.Println(":P")
os.Exit(1)
}
path := os.Args[1]
if path == "help" {
fmt.Println("Options:")
fmt.Println(" -r reverse the char color.")
fmt.Println(" -g enable gif analyzation, default: disable.")
fmt.Println(" -s [d](0, +) set the scale of art. [default: 0.5]")
fmt.Println(" -t [d][0, 255] set the threshold of binarization. [default: gen by ostu]")
os.Exit(0)
} else if path == "version" {
fmt.Printf("BoBiBo %s :P\n", version)
os.Exit(0)
}
f, err := os.Open(path)
defer f.Close()
flag.Parse()
args := flag.Args()

if err != nil {
fmt.Println(err.Error())
if len(args) < 1 {
fmt.Fprintln(os.Stderr, "Usage: bobibo [OPTION]... PARTERNS [FILE]...")
fmt.Fprintln(os.Stderr, "Try 'bobibo --help' for more information.")
os.Exit(1)
}

var gif, rever bool
var scale float64 = 0.5
var threshold = -1
for i, v := range os.Args[2:] {
switch v {
case "-g":
gif = true
case "-r":
rever = true
case "-s":
f, err := strconv.ParseFloat(os.Args[i+3], 64)
if err != nil {
fmt.Println("The range of scale must at (0, +).")
os.Exit(1)
}
if f == 0 {
fmt.Println("The range of scale must at (0, +).")
os.Exit(1)
}
scale = f
case "-t":
i, err := strconv.ParseInt(os.Args[i+3], 10, 64)
if err != nil {
fmt.Println("The range of threshold must at [0, 255].")
os.Exit(1)
}
if i < 0 || i > 255 {
fmt.Println("The range of threshold must at [0, 255].")
os.Exit(1)
}
threshold = int(i)
opt := args[0]
var imgFile *os.File

switch opt {
case "version":
fmt.Printf("BoBiBo %s :P\n", version)
return
default:
f, err := os.Open(opt)
if err != nil {
fmt.Fprintln(os.Stderr, "Open image error: ", err.Error())
}
imgFile = f
}

out, err := bobibo.BoBiBo(f, gif, rever, scale, threshold)
defer imgFile.Close()
arts, err := bobibo.BoBiBo(
imgFile, gif, inverse,
bobibo.ScaleOpt(scale),
bobibo.ThresholdOpt(threshold))
if err != nil {
fmt.Println(err.Error())
fmt.Fprintln(os.Stderr, "Bobibo error: ", err.Error())
imgFile.Close()
os.Exit(1)
}

for e := range out {
for _, v := range e {
fmt.Printf("\r%s\n", v)
}
err = printArts(arts, gif)
if err != nil {
fmt.Fprintln(os.Stderr, "Print error: ", err.Error())
imgFile.Close()
os.Exit(1)
}
}
3 changes: 1 addition & 2 deletions cli/makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
VERSION=V1.1.0
VERSION=V1.2.0
EXE=bobibo
DESTDIR :=

Expand All @@ -8,7 +8,6 @@ default: build
.PHONY: build
build: cli.go
go build -ldflags="-X 'main.version=$(VERSION)' -s -w" -o $(EXE)
upx $(EXE) # upx not found ? install it or remove this line.
@echo Build Success !!!

.PHONY: install
Expand Down
4 changes: 2 additions & 2 deletions cli/makefile_cross
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
OS = linux
OS = windows
ARCH = amd64
EXE = bobibo_$(OS)_$(ARCH)
IS_STATIC = 0
VERSION=V1.1.0
VERSION=V1.2.0
all: build

build: cli.go
Expand Down
Loading

0 comments on commit e827654

Please sign in to comment.