From d72540d0c3865ce03ae51c8849a059c67da88565 Mon Sep 17 00:00:00 2001 From: Dmitry Fedotov Date: Wed, 26 Mar 2025 00:51:46 +0300 Subject: [PATCH] add video encoding. broken for now --- go.mod | 2 +- image.go | 4 ++-- main.go | 21 +++++++++++++++++---- settings.go | 36 +++++++++++++++++++++--------------- video.go | 38 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 79 insertions(+), 22 deletions(-) create mode 100644 video.go diff --git a/go.mod b/go.mod index cc9bd77..01b0c92 100644 --- a/go.mod +++ b/go.mod @@ -2,4 +2,4 @@ module code.uint32.ru/dmitry/barnsley-fern-go go 1.24.1 -require github.com/AlexEidt/Vidio v1.5.1 // indirect +require github.com/AlexEidt/Vidio v1.5.1 diff --git a/image.go b/image.go index bf20338..fbc86f7 100644 --- a/image.go +++ b/image.go @@ -8,7 +8,7 @@ import ( "io" ) -var erreEcnodePng = errors.New("не удалось создать png изображение") +var errEncodePng = errors.New("не удалось создать png изображение") func createBarnsleyFernPng(s *settings, w io.Writer) error { img := newImageWithBackGround(s.X, s.Y, s.BG) @@ -16,7 +16,7 @@ func createBarnsleyFernPng(s *settings, w io.Writer) error { drawBarnsleyFern(img, newColorFunc(s.CM), s.Dots) if err := png.Encode(w, img); err != nil { - return errors.Join(erreEcnodePng, err) + return errors.Join(errEncodePng, err) } return nil diff --git a/main.go b/main.go index 1b767ca..10de3e8 100644 --- a/main.go +++ b/main.go @@ -2,13 +2,26 @@ package main import ( "fmt" + "io" "os" ) func main() { - filename, settings := parseSettings() + s := parseSettings() - file, err := os.Create(filename) + var processor func(*settings, io.Writer) error + + switch s.OM { + case outputpng: + processor = createBarnsleyFernPng + case outputvideo: + processor = createBarnsLeyFernVideo + default: + fmt.Println("неизвестный тип вывода:", s.OM) + return + } + + file, err := os.Create(s.Fname) if err != nil { fmt.Println("ошибка открытия файла", err) return @@ -20,8 +33,8 @@ func main() { } }() - if err := createBarnsleyFernPng(settings, file); err != nil { - fmt.Println("ошибка создания изображения:", err) + if err := processor(s, file); err != nil { + fmt.Println("ошибка создания объекта:", err) return } diff --git a/settings.go b/settings.go index ebc650a..8b67c6f 100644 --- a/settings.go +++ b/settings.go @@ -22,35 +22,41 @@ const ( ) type settings struct { - X, Y int // image size - Dots int // dots to draw for single image - BG color.Color // background color - CM colormode // settings for colorFunc + X, Y int // image size + Dots int // dots to draw for single image + BG color.Color // background color + CM colormode // settings for colorFunc + OM outputmode // what to output + Fname string // filename for output } -func parseSettings() (string, *settings) { +func parseSettings() *settings { var ( - x, y int - dots int - cmode int - fname string + x, y int + dots int + cmode int + output int + fname string ) flag.IntVar(&x, "x", 1920, "размер картинки по горизонтали") flag.IntVar(&y, "y", 1080, "размер картинки по вертикали") flag.IntVar(&dots, "d", 100000, "сколько точек рисовать") flag.IntVar(&cmode, "color", 0, "color mode: 0 - default green, 1 - random, 2 - timed, 3 - rainbow") + flag.IntVar(&output, "o", 0, "режим вывода: 0 - изображение png, 1 - видео") flag.StringVar(&fname, "out", "barnsley-fern.png", "полный путь файла для записи изображения") flag.Parse() s := &settings{ - X: x, - Y: y, - Dots: dots, - BG: color.White, - CM: colormode(cmode), + X: x, + Y: y, + Dots: dots, + BG: color.White, + CM: colormode(cmode), + OM: outputmode(output), + Fname: fname, } - return fname, s + return s } diff --git a/video.go b/video.go new file mode 100644 index 0000000..d6f3d9b --- /dev/null +++ b/video.go @@ -0,0 +1,38 @@ +package main + +import ( + "bytes" + "errors" + "io" + + vid "github.com/AlexEidt/Vidio" +) + +var erreEncodeVideo = errors.New("не удалось создать видео") + +func createBarnsLeyFernVideo(s *settings, w io.Writer) error { + opts := &vid.Options{ + FPS: 1, + Quality: 0, + Delay: 1000, + } + + vw, err := vid.NewVideoWriter(s.Fname, s.X, s.Y, opts) + if err != nil { + return errors.Join(erreEncodeVideo, err) + } + + frames := 100 + for range frames { + imgbuf := new(bytes.Buffer) + if err := createBarnsleyFernPng(s, imgbuf); err != nil { + return errors.Join(erreEncodeVideo, err) + } + + if err := vw.Write(imgbuf.Bytes()); err != nil { + return errors.Join(erreEncodeVideo, err) + } + } + + return nil +}