From 69f5d1ccb3dd7d905cea437bd1861bbe70da77dd Mon Sep 17 00:00:00 2001 From: David Vogel Date: Mon, 15 Jan 2024 20:06:49 +0100 Subject: [PATCH] Add WebP encoder --- .vscode/settings.json | 1 + bin/stitch/export-webp.go | 40 +++++++++++++++++++++++++++++++++++++++ bin/stitch/main.go | 8 ++++++-- go.mod | 1 + go.sum | 2 ++ 5 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 bin/stitch/export-webp.go diff --git a/.vscode/settings.json b/.vscode/settings.json index 9e5718a..456ba78 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -54,6 +54,7 @@ "upscaled", "Vogel", "Voronoi", + "webp", "xmax", "xmin", "ymax", diff --git a/bin/stitch/export-webp.go b/bin/stitch/export-webp.go new file mode 100644 index 0000000..2fa3b46 --- /dev/null +++ b/bin/stitch/export-webp.go @@ -0,0 +1,40 @@ +// 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" + + "github.com/chai2010/webp" +) + +func exportWebP(stitchedImage image.Image, outputPath string) error { + log.Printf("Creating output file %q.", outputPath) + + return exportWebPSilent(stitchedImage, outputPath) +} + +func exportWebPSilent(stitchedImage image.Image, outputPath string) error { + bounds := stitchedImage.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() + + if err = webp.Encode(f, stitchedImage, &webp.Options{Lossless: true}); err != nil { + return fmt.Errorf("failed to encode image %q: %w", outputPath, err) + } + + return nil +} diff --git a/bin/stitch/main.go b/bin/stitch/main.go index 6f9e3fd..ddee631 100644 --- a/bin/stitch/main.go +++ b/bin/stitch/main.go @@ -1,4 +1,4 @@ -// Copyright (c) 2019-2023 David Vogel +// Copyright (c) 2019-2024 David Vogel // // This software is released under the MIT License. // https://opensource.org/licenses/MIT @@ -22,7 +22,7 @@ import ( var flagInputPath = flag.String("input", filepath.Join(".", "..", "..", "output"), "The source path of the image tiles to be stitched.") var flagEntitiesInputPath = flag.String("entities", filepath.Join(".", "..", "..", "output", "entities.json"), "The path to the entities.json file.") var flagPlayerPathInputPath = flag.String("player-path", filepath.Join(".", "..", "..", "output", "player-path.json"), "The path to the player-path.json file.") -var flagOutputPath = flag.String("output", filepath.Join(".", "output.png"), "The path and filename of the resulting stitched image. Supported formats/file extensions: `.png`, `.jpg`, `.dzi`.") +var flagOutputPath = flag.String("output", filepath.Join(".", "output.png"), "The path and filename of the resulting stitched image. Supported formats/file extensions: `.png`, `.webp`, `.jpg`, `.dzi`.") var flagScaleDivider = flag.Int("divide", 1, "A downscaling factor. 2 will produce an image with half the side lengths.") var flagBlendTileLimit = flag.Int("blend-tile-limit", 9, "Limits median blending to the n newest tiles by file modification time. If set to 0, all available tiles will be median blended.") var flagDZITileSize = flag.Int("dzi-tile-size", 512, "The size of the resulting deep zoom image (DZI) tiles in pixels.") @@ -333,6 +333,10 @@ func main() { if err := exportJPEG(stitchedImage, *flagOutputPath); err != nil { log.Panicf("Export of JPEG file failed: %v", err) } + case ".webp": + if err := exportWebP(stitchedImage, *flagOutputPath); err != nil { + log.Panicf("Export of WebP file failed: %v", err) + } case ".dzi": if err := exportDZI(stitchedImage, *flagOutputPath, *flagDZITileSize, *flagDZIOverlap); err != nil { log.Panicf("Export of DZI file failed: %v", err) diff --git a/go.mod b/go.mod index bbda108..d8c9e9f 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.21 require ( github.com/1lann/promptui v0.8.1-0.20220708222609-81fad96dd5e1 + github.com/chai2010/webp v1.1.1 github.com/cheggaaa/pb/v3 v3.1.4 github.com/coreos/go-semver v0.3.1 github.com/kbinani/screenshot v0.0.0-20230812210009-b87d31814237 diff --git a/go.sum b/go.sum index 3f0f526..f92e117 100644 --- a/go.sum +++ b/go.sum @@ -16,6 +16,8 @@ github.com/benoitkugler/textprocessing v0.0.3 h1:Q2X+Z6vxuW5Bxn1R9RaNt0qcprBfpc2 github.com/benoitkugler/textprocessing v0.0.3/go.mod h1:/4bLyCf1QYywunMK3Gf89Nhb50YI/9POewqrLxWhxd4= github.com/campoy/embedmd v1.0.0 h1:V4kI2qTJJLf4J29RzI/MAt2c3Bl4dQSYPuflzwFH2hY= github.com/campoy/embedmd v1.0.0/go.mod h1:oxyr9RCiSXg0M3VJ3ks0UGfp98BpSSGr0kpiX3MzVl8= +github.com/chai2010/webp v1.1.1 h1:jTRmEccAJ4MGrhFOrPMpNGIJ/eybIgwKpcACsrTEapk= +github.com/chai2010/webp v1.1.1/go.mod h1:0XVwvZWdjjdxpUEIf7b9g9VkHFnInUSYujwqTLEuldU= github.com/cheggaaa/pb/v3 v3.1.4 h1:DN8j4TVVdKu3WxVwcRKu0sG00IIU6FewoABZzXbRQeo= github.com/cheggaaa/pb/v3 v3.1.4/go.mod h1:6wVjILNBaXMs8c21qRiaUM8BR82erfgau1DQ4iUXmSA= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=