noita-mapcap/bin/stitch/export-webp.go
David Vogel b1a10870c1 Several changes
- Add compatibility for newest Noita beta
- Modify STREAMING_CHUNK_TARGET, GRID_MAX_UPDATES_PER_FRAME and GRID_MIN_UPDATES_PER_FRAME magic numbers for a more robust capturing process
- Add LimitGroup to util.go
- Add webp-level command line flag to define the webp compression level
- Rework progress bar to make it work in DZI export mode
- Refactor image exporter functions
- Use LimitGroup to make DZI export multithreaded
- Add BlendMethodFast which doesn't mix tile pixels
- Up Go version to 1.22
- Use Dadido3/go-libwebp for WebP encoding
2024-02-08 00:50:11 +01:00

74 lines
1.8 KiB
Go

// 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
}