// Copyright (c) 2024 David Vogel // // This software is released under the MIT License. // https://opensource.org/licenses/MIT package main import ( "fmt" "image" "log" "os" "time" "github.com/Dadido3/go-libwebp/webp" "github.com/cheggaaa/pb/v3" ) func exportWebPStitchedImage(stitchedImage *StitchedImage, outputPath string, bar *pb.ProgressBar, webPLevel int) error { log.Printf("Creating output file %q.", outputPath) // If there is a progress bar, start a goroutine that regularly updates it. // We will base the progress on the number of pixels read from the stitched image. if bar != nil { _, max := stitchedImage.Progress() bar.SetRefreshRate(250 * time.Millisecond).SetTotal(int64(max)).Start() done := make(chan struct{}) defer func() { done <- struct{}{} bar.SetCurrent(bar.Total()).Finish() }() go func() { ticker := time.NewTicker(250 * time.Millisecond) for { select { case <-done: return case <-ticker.C: value, max := stitchedImage.Progress() bar.SetCurrent(int64(value)).SetTotal(int64(max)) } } }() } return exportWebP(stitchedImage, outputPath, webPLevel) } func exportWebP(img image.Image, outputPath string, webPLevel int) error { bounds := img.Bounds() if bounds.Dx() > 16383 || bounds.Dy() > 16383 { return fmt.Errorf("image size exceeds the maximum allowed size (16383) of a WebP image: %d x %d", bounds.Dx(), bounds.Dy()) } f, err := os.Create(outputPath) if err != nil { return fmt.Errorf("failed to create file: %w", err) } defer f.Close() webPConfig, err := webp.ConfigLosslessPreset(webPLevel) if err != nil { return fmt.Errorf("failed to create webP config: %v", err) } if err = webp.Encode(f, img, webPConfig); err != nil { return fmt.Errorf("failed to encode image %q: %w", outputPath, err) } return nil }