mirror of
https://github.com/gen2brain/cbconvert
synced 2025-10-13 18:18:52 +02:00
Use bild library
This commit is contained in:
55
cbconvert.go
55
cbconvert.go
@@ -24,7 +24,6 @@ import (
|
|||||||
"github.com/gen2brain/webp"
|
"github.com/gen2brain/webp"
|
||||||
"golang.org/x/image/tiff"
|
"golang.org/x/image/tiff"
|
||||||
|
|
||||||
"github.com/disintegration/imaging"
|
|
||||||
pngstructure "github.com/dsoprea/go-png-image-structure"
|
pngstructure "github.com/dsoprea/go-png-image-structure"
|
||||||
"github.com/dustin/go-humanize"
|
"github.com/dustin/go-humanize"
|
||||||
"github.com/fvbommel/sortorder"
|
"github.com/fvbommel/sortorder"
|
||||||
@@ -33,34 +32,6 @@ import (
|
|||||||
"golang.org/x/sync/errgroup"
|
"golang.org/x/sync/errgroup"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Resample filters.
|
|
||||||
const (
|
|
||||||
// NearestNeighbor is the fastest resampling filter, no antialiasing.
|
|
||||||
NearestNeighbor int = iota
|
|
||||||
// Box filter (averaging pixels).
|
|
||||||
Box
|
|
||||||
// Linear is the bilinear filter, smooth and reasonably fast.
|
|
||||||
Linear
|
|
||||||
// MitchellNetravali is a smooth bicubic filter.
|
|
||||||
MitchellNetravali
|
|
||||||
// CatmullRom is a sharp bicubic filter.
|
|
||||||
CatmullRom
|
|
||||||
// Gaussian is a blurring filter that uses gaussian function, useful for noise removal.
|
|
||||||
Gaussian
|
|
||||||
// Lanczos is a high-quality resampling filter, it's slower than cubic filters.
|
|
||||||
Lanczos
|
|
||||||
)
|
|
||||||
|
|
||||||
var filters = map[int]imaging.ResampleFilter{
|
|
||||||
NearestNeighbor: imaging.NearestNeighbor,
|
|
||||||
Box: imaging.Box,
|
|
||||||
Linear: imaging.Linear,
|
|
||||||
MitchellNetravali: imaging.MitchellNetravali,
|
|
||||||
CatmullRom: imaging.CatmullRom,
|
|
||||||
Gaussian: imaging.Gaussian,
|
|
||||||
Lanczos: imaging.Lanczos,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Options type.
|
// Options type.
|
||||||
type Options struct {
|
type Options struct {
|
||||||
// Image format, valid values are jpeg, png, tiff, bmp, webp, avif, jxl
|
// Image format, valid values are jpeg, png, tiff, bmp, webp, avif, jxl
|
||||||
@@ -480,29 +451,29 @@ func (c *Converter) imageTransform(img image.Image) image.Image {
|
|||||||
|
|
||||||
if c.Opts.Width > 0 || c.Opts.Height > 0 {
|
if c.Opts.Width > 0 || c.Opts.Height > 0 {
|
||||||
if c.Opts.Fit {
|
if c.Opts.Fit {
|
||||||
i = imaging.Fit(i, c.Opts.Width, c.Opts.Height, filters[c.Opts.Filter])
|
i = fit(i, c.Opts.Width, c.Opts.Height, filters[c.Opts.Filter])
|
||||||
} else {
|
} else {
|
||||||
i = imaging.Resize(i, c.Opts.Width, c.Opts.Height, filters[c.Opts.Filter])
|
i = resize(i, c.Opts.Width, c.Opts.Height, filters[c.Opts.Filter])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.Opts.Rotate > 0 {
|
if c.Opts.Rotate > 0 {
|
||||||
switch c.Opts.Rotate {
|
switch c.Opts.Rotate {
|
||||||
case 90:
|
case 90:
|
||||||
i = imaging.Rotate90(i)
|
i = rotate(i, 90)
|
||||||
case 180:
|
case 180:
|
||||||
i = imaging.Rotate180(i)
|
i = rotate(i, 180)
|
||||||
case 270:
|
case 270:
|
||||||
i = imaging.Rotate270(i)
|
i = rotate(i, 270)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.Opts.Brightness != 0 {
|
if c.Opts.Brightness != 0 {
|
||||||
i = imaging.AdjustBrightness(i, float64(c.Opts.Brightness))
|
i = brightness(i, float64(c.Opts.Brightness))
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.Opts.Contrast != 0 {
|
if c.Opts.Contrast != 0 {
|
||||||
i = imaging.AdjustContrast(i, float64(c.Opts.Contrast))
|
i = contrast(i, float64(c.Opts.Contrast))
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.Opts.Grayscale {
|
if c.Opts.Grayscale {
|
||||||
@@ -811,9 +782,9 @@ func (c *Converter) Cover(fileName string, fileInfo os.FileInfo) error {
|
|||||||
|
|
||||||
if c.Opts.Width > 0 || c.Opts.Height > 0 {
|
if c.Opts.Width > 0 || c.Opts.Height > 0 {
|
||||||
if c.Opts.Fit {
|
if c.Opts.Fit {
|
||||||
cover = imaging.Fit(cover, c.Opts.Width, c.Opts.Height, filters[c.Opts.Filter])
|
cover = fit(cover, c.Opts.Width, c.Opts.Height, filters[c.Opts.Filter])
|
||||||
} else {
|
} else {
|
||||||
cover = imaging.Resize(cover, c.Opts.Width, c.Opts.Height, filters[c.Opts.Filter])
|
cover = resize(cover, c.Opts.Width, c.Opts.Height, filters[c.Opts.Filter])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -853,12 +824,12 @@ func (c *Converter) Thumbnail(fileName string, fileInfo os.FileInfo) error {
|
|||||||
|
|
||||||
if c.Opts.Width > 0 || c.Opts.Height > 0 {
|
if c.Opts.Width > 0 || c.Opts.Height > 0 {
|
||||||
if c.Opts.Fit {
|
if c.Opts.Fit {
|
||||||
cover = imaging.Fit(cover, c.Opts.Width, c.Opts.Height, filters[c.Opts.Filter])
|
cover = fit(cover, c.Opts.Width, c.Opts.Height, filters[c.Opts.Filter])
|
||||||
} else {
|
} else {
|
||||||
cover = imaging.Resize(cover, c.Opts.Width, c.Opts.Height, filters[c.Opts.Filter])
|
cover = resize(cover, c.Opts.Width, c.Opts.Height, filters[c.Opts.Filter])
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cover = imaging.Resize(cover, 256, 0, filters[c.Opts.Filter])
|
cover = resize(cover, 256, 0, filters[c.Opts.Filter])
|
||||||
}
|
}
|
||||||
|
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
@@ -1019,7 +990,7 @@ func (c *Converter) Preview(fileName string, fileInfo os.FileInfo, width, height
|
|||||||
}
|
}
|
||||||
|
|
||||||
if width != 0 && height != 0 {
|
if width != 0 && height != 0 {
|
||||||
dec = imaging.Fit(dec, width, height, filters[c.Opts.Filter])
|
dec = fit(dec, width, height, filters[c.Opts.Filter])
|
||||||
}
|
}
|
||||||
|
|
||||||
img.Image = dec
|
img.Image = dec
|
||||||
|
@@ -2,41 +2,12 @@ package cbconvert
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"image"
|
|
||||||
"image/color"
|
|
||||||
"image/draw"
|
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// imageToRGBA converts an image.Image to *image.RGBA.
|
|
||||||
func imageToRGBA(src image.Image) *image.RGBA {
|
|
||||||
if dst, ok := src.(*image.RGBA); ok {
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
b := src.Bounds()
|
|
||||||
dst := image.NewRGBA(b)
|
|
||||||
draw.Draw(dst, dst.Bounds(), src, b.Min, draw.Src)
|
|
||||||
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// imageToGray converts an image.Image to *image.Gray.
|
|
||||||
func imageToGray(src image.Image) *image.Gray {
|
|
||||||
if dst, ok := src.(*image.Gray); ok {
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
b := src.Bounds()
|
|
||||||
dst := image.NewGray(b)
|
|
||||||
draw.Draw(dst, dst.Bounds(), src, b.Min, draw.Src)
|
|
||||||
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// imagesFromPath returns list of found image files for given directory.
|
// imagesFromPath returns list of found image files for given directory.
|
||||||
func imagesFromPath(path string) ([]string, error) {
|
func imagesFromPath(path string) ([]string, error) {
|
||||||
var images []string
|
var images []string
|
||||||
@@ -147,16 +118,6 @@ func isSize(a, b int64) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// isGrayScale checks if image is grayscale.
|
|
||||||
func isGrayScale(img image.Image) bool {
|
|
||||||
model := img.ColorModel()
|
|
||||||
if model == color.GrayModel || model == color.Gray16Model {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// baseNoExt returns base name without extension.
|
// baseNoExt returns base name without extension.
|
||||||
func baseNoExt(filename string) string {
|
func baseNoExt(filename string) string {
|
||||||
return strings.TrimSuffix(filepath.Base(filename), filepath.Ext(filename))
|
return strings.TrimSuffix(filepath.Base(filename), filepath.Ext(filename))
|
||||||
|
135
cbconvert_image.go
Normal file
135
cbconvert_image.go
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
package cbconvert
|
||||||
|
|
||||||
|
import (
|
||||||
|
"image"
|
||||||
|
"image/color"
|
||||||
|
"image/draw"
|
||||||
|
"math"
|
||||||
|
|
||||||
|
"github.com/anthonynsimon/bild/adjust"
|
||||||
|
"github.com/anthonynsimon/bild/transform"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Resample filters.
|
||||||
|
const (
|
||||||
|
// NearestNeighbor is the fastest resampling filter, no antialiasing.
|
||||||
|
NearestNeighbor int = iota
|
||||||
|
// Box filter (averaging pixels).
|
||||||
|
Box
|
||||||
|
// Linear is the bilinear filter, smooth and reasonably fast.
|
||||||
|
Linear
|
||||||
|
// MitchellNetravali is a smooth bicubic filter.
|
||||||
|
MitchellNetravali
|
||||||
|
// CatmullRom is a sharp bicubic filter.
|
||||||
|
CatmullRom
|
||||||
|
// Gaussian is a blurring filter that uses gaussian function, useful for noise removal.
|
||||||
|
Gaussian
|
||||||
|
// Lanczos is a high-quality resampling filter, it's slower than cubic filters.
|
||||||
|
Lanczos
|
||||||
|
)
|
||||||
|
|
||||||
|
var filters = map[int]transform.ResampleFilter{
|
||||||
|
NearestNeighbor: transform.NearestNeighbor,
|
||||||
|
Box: transform.Box,
|
||||||
|
Linear: transform.Linear,
|
||||||
|
MitchellNetravali: transform.MitchellNetravali,
|
||||||
|
CatmullRom: transform.CatmullRom,
|
||||||
|
Gaussian: transform.Gaussian,
|
||||||
|
Lanczos: transform.Lanczos,
|
||||||
|
}
|
||||||
|
|
||||||
|
func resize(img image.Image, width, height int, filter transform.ResampleFilter) *image.RGBA {
|
||||||
|
dstW, dstH := width, height
|
||||||
|
|
||||||
|
srcW := img.Bounds().Dx()
|
||||||
|
srcH := img.Bounds().Dy()
|
||||||
|
|
||||||
|
if dstW == 0 {
|
||||||
|
tmpW := float64(dstH) * float64(srcW) / float64(srcH)
|
||||||
|
dstW = int(math.Max(1.0, math.Floor(tmpW+0.5)))
|
||||||
|
}
|
||||||
|
if dstH == 0 {
|
||||||
|
tmpH := float64(dstW) * float64(srcH) / float64(srcW)
|
||||||
|
dstH = int(math.Max(1.0, math.Floor(tmpH+0.5)))
|
||||||
|
}
|
||||||
|
|
||||||
|
if srcW == dstW && srcH == dstH {
|
||||||
|
return imageToRGBA(img)
|
||||||
|
}
|
||||||
|
|
||||||
|
return transform.Resize(img, dstW, dstH, filter)
|
||||||
|
}
|
||||||
|
|
||||||
|
func fit(img image.Image, width, height int, filter transform.ResampleFilter) *image.RGBA {
|
||||||
|
maxW, maxH := width, height
|
||||||
|
|
||||||
|
b := img.Bounds()
|
||||||
|
srcW := b.Dx()
|
||||||
|
srcH := b.Dy()
|
||||||
|
|
||||||
|
if srcW <= maxW && srcH <= maxH {
|
||||||
|
return imageToRGBA(img)
|
||||||
|
}
|
||||||
|
|
||||||
|
srcAspectRatio := float64(srcW) / float64(srcH)
|
||||||
|
maxAspectRatio := float64(maxW) / float64(maxH)
|
||||||
|
|
||||||
|
var dstW, dstH int
|
||||||
|
if srcAspectRatio > maxAspectRatio {
|
||||||
|
dstW = maxW
|
||||||
|
dstH = int(float64(dstW) / srcAspectRatio)
|
||||||
|
} else {
|
||||||
|
dstH = maxH
|
||||||
|
dstW = int(float64(dstH) * srcAspectRatio)
|
||||||
|
}
|
||||||
|
|
||||||
|
return resize(img, dstW, dstH, filter)
|
||||||
|
}
|
||||||
|
|
||||||
|
func rotate(img image.Image, angle float64) *image.RGBA {
|
||||||
|
return transform.Rotate(img, angle, &transform.RotationOptions{ResizeBounds: true, Pivot: &image.Point{}})
|
||||||
|
}
|
||||||
|
|
||||||
|
func brightness(img image.Image, change float64) *image.RGBA {
|
||||||
|
return adjust.Brightness(img, change/100)
|
||||||
|
}
|
||||||
|
|
||||||
|
func contrast(img image.Image, change float64) *image.RGBA {
|
||||||
|
return adjust.Contrast(img, change/100)
|
||||||
|
}
|
||||||
|
|
||||||
|
// imageToRGBA converts an image.Image to *image.RGBA.
|
||||||
|
func imageToRGBA(src image.Image) *image.RGBA {
|
||||||
|
if dst, ok := src.(*image.RGBA); ok {
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
b := src.Bounds()
|
||||||
|
dst := image.NewRGBA(b)
|
||||||
|
draw.Draw(dst, dst.Bounds(), src, b.Min, draw.Src)
|
||||||
|
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// imageToGray converts an image.Image to *image.Gray.
|
||||||
|
func imageToGray(src image.Image) *image.Gray {
|
||||||
|
if dst, ok := src.(*image.Gray); ok {
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
b := src.Bounds()
|
||||||
|
dst := image.NewGray(b)
|
||||||
|
draw.Draw(dst, dst.Bounds(), src, b.Min, draw.Src)
|
||||||
|
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// isGrayScale checks if image is grayscale.
|
||||||
|
func isGrayScale(img image.Image) bool {
|
||||||
|
model := img.ColorModel()
|
||||||
|
if model == color.GrayModel || model == color.Gray16Model {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
16
go.mod
16
go.mod
@@ -3,7 +3,7 @@ module github.com/gen2brain/cbconvert
|
|||||||
go 1.23
|
go 1.23
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/disintegration/imaging v1.6.2
|
github.com/anthonynsimon/bild v0.14.0
|
||||||
github.com/dsoprea/go-png-image-structure v0.0.0-20210512210324-29b889a6093d
|
github.com/dsoprea/go-png-image-structure v0.0.0-20210512210324-29b889a6093d
|
||||||
github.com/dustin/go-humanize v1.0.1
|
github.com/dustin/go-humanize v1.0.1
|
||||||
github.com/fvbommel/sortorder v1.1.0
|
github.com/fvbommel/sortorder v1.1.0
|
||||||
@@ -17,14 +17,14 @@ require (
|
|||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/dsoprea/go-exif/v2 v2.0.0-20200604193436-ca8584a0e1c4 // indirect
|
github.com/dsoprea/go-exif/v2 v2.0.0-20230826092837-6579e82b732d // indirect
|
||||||
github.com/dsoprea/go-logging v0.0.0-20200517223158-a10564966e9d // indirect
|
github.com/dsoprea/go-logging v0.0.0-20200710184922-b02d349568dd // indirect
|
||||||
github.com/dsoprea/go-utility v0.0.0-20200711062821-fab8125e9bdf // indirect
|
github.com/dsoprea/go-utility v0.0.0-20221003172846-a3e1774ef349 // indirect
|
||||||
github.com/ebitengine/purego v0.8.1 // indirect
|
github.com/ebitengine/purego v0.8.1 // indirect
|
||||||
github.com/go-errors/errors v1.1.1 // indirect
|
github.com/go-errors/errors v1.5.1 // indirect
|
||||||
github.com/golang/geo v0.0.0-20200319012246-673a6f80352d // indirect
|
github.com/golang/geo v0.0.0-20230421003525-6adc56603217 // indirect
|
||||||
github.com/jupiterrider/ffi v0.2.1 // indirect
|
github.com/jupiterrider/ffi v0.2.1 // indirect
|
||||||
github.com/tetratelabs/wazero v1.8.1 // indirect
|
github.com/tetratelabs/wazero v1.8.1 // indirect
|
||||||
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2 // indirect
|
golang.org/x/net v0.30.0 // indirect
|
||||||
gopkg.in/yaml.v2 v2.3.0 // indirect
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
)
|
)
|
||||||
|
26
go.sum
26
go.sum
@@ -1,17 +1,20 @@
|
|||||||
github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c=
|
github.com/anthonynsimon/bild v0.14.0 h1:IFRkmKdNdqmexXHfEU7rPlAmdUZ8BDZEGtGHDnGWync=
|
||||||
github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
|
github.com/anthonynsimon/bild v0.14.0/go.mod h1:hcvEAyBjTW69qkKJTfpcDQ83sSZHxwOunsseDfeQhUs=
|
||||||
github.com/dsoprea/go-exif/v2 v2.0.0-20200321225314-640175a69fe4/go.mod h1:Lm2lMM2zx8p4a34ZemkaUV95AnMl4ZvLbCUbwOvLC2E=
|
github.com/dsoprea/go-exif/v2 v2.0.0-20200321225314-640175a69fe4/go.mod h1:Lm2lMM2zx8p4a34ZemkaUV95AnMl4ZvLbCUbwOvLC2E=
|
||||||
github.com/dsoprea/go-exif/v2 v2.0.0-20200604193436-ca8584a0e1c4 h1:Mg7pY7kxDQD2Bkvr1N+XW4BESSIQ7tTTR7Vv+Gi2CsM=
|
|
||||||
github.com/dsoprea/go-exif/v2 v2.0.0-20200604193436-ca8584a0e1c4/go.mod h1:9EXlPeHfblFFnwu5UOqmP2eoZfJyAZ2Ri/Vki33ajO0=
|
github.com/dsoprea/go-exif/v2 v2.0.0-20200604193436-ca8584a0e1c4/go.mod h1:9EXlPeHfblFFnwu5UOqmP2eoZfJyAZ2Ri/Vki33ajO0=
|
||||||
|
github.com/dsoprea/go-exif/v2 v2.0.0-20230826092837-6579e82b732d h1:yeH8wrJa3+8uKKDAdURHUK1ds2UvKhMqX2MiOdVeKPs=
|
||||||
|
github.com/dsoprea/go-exif/v2 v2.0.0-20230826092837-6579e82b732d/go.mod h1:oKrjk2kb3rAR5NbtSTLUMvMSbc+k8ZosI3MaVH47noc=
|
||||||
github.com/dsoprea/go-exif/v3 v3.0.0-20200717053412-08f1b6708903/go.mod h1:0nsO1ce0mh5czxGeLo4+OCZ/C6Eo6ZlMWsz7rH/Gxv8=
|
github.com/dsoprea/go-exif/v3 v3.0.0-20200717053412-08f1b6708903/go.mod h1:0nsO1ce0mh5czxGeLo4+OCZ/C6Eo6ZlMWsz7rH/Gxv8=
|
||||||
github.com/dsoprea/go-exif/v3 v3.0.0-20210512043655-120bcdb2a55e/go.mod h1:cg5SNYKHMmzxsr9X6ZeLh/nfBRHHp5PngtEPcujONtk=
|
github.com/dsoprea/go-exif/v3 v3.0.0-20210512043655-120bcdb2a55e/go.mod h1:cg5SNYKHMmzxsr9X6ZeLh/nfBRHHp5PngtEPcujONtk=
|
||||||
github.com/dsoprea/go-logging v0.0.0-20190624164917-c4f10aab7696/go.mod h1:Nm/x2ZUNRW6Fe5C3LxdY1PyZY5wmDv/s5dkPJ/VB3iA=
|
github.com/dsoprea/go-logging v0.0.0-20190624164917-c4f10aab7696/go.mod h1:Nm/x2ZUNRW6Fe5C3LxdY1PyZY5wmDv/s5dkPJ/VB3iA=
|
||||||
github.com/dsoprea/go-logging v0.0.0-20200517223158-a10564966e9d h1:F/7L5wr/fP/SKeO5HuMlNEX9Ipyx2MbH2rV9G4zJRpk=
|
|
||||||
github.com/dsoprea/go-logging v0.0.0-20200517223158-a10564966e9d/go.mod h1:7I+3Pe2o/YSU88W0hWlm9S22W7XI1JFNJ86U0zPKMf8=
|
github.com/dsoprea/go-logging v0.0.0-20200517223158-a10564966e9d/go.mod h1:7I+3Pe2o/YSU88W0hWlm9S22W7XI1JFNJ86U0zPKMf8=
|
||||||
|
github.com/dsoprea/go-logging v0.0.0-20200710184922-b02d349568dd h1:l+vLbuxptsC6VQyQsfD7NnEC8BZuFpz45PgY+pH8YTg=
|
||||||
|
github.com/dsoprea/go-logging v0.0.0-20200710184922-b02d349568dd/go.mod h1:7I+3Pe2o/YSU88W0hWlm9S22W7XI1JFNJ86U0zPKMf8=
|
||||||
github.com/dsoprea/go-png-image-structure v0.0.0-20210512210324-29b889a6093d h1:8+qI8ant/vZkNSsbwSjIR6XJfWcDVTg/qx/3pRUUZNA=
|
github.com/dsoprea/go-png-image-structure v0.0.0-20210512210324-29b889a6093d h1:8+qI8ant/vZkNSsbwSjIR6XJfWcDVTg/qx/3pRUUZNA=
|
||||||
github.com/dsoprea/go-png-image-structure v0.0.0-20210512210324-29b889a6093d/go.mod h1:yTR3tKgyk20phAFg6IE9ulMA5NjEDD2wyx+okRFLVtw=
|
github.com/dsoprea/go-png-image-structure v0.0.0-20210512210324-29b889a6093d/go.mod h1:yTR3tKgyk20phAFg6IE9ulMA5NjEDD2wyx+okRFLVtw=
|
||||||
github.com/dsoprea/go-utility v0.0.0-20200711062821-fab8125e9bdf h1:/w4QxepU4AHh3AuO6/g8y/YIIHH5+aKP3Bj8sg5cqhU=
|
|
||||||
github.com/dsoprea/go-utility v0.0.0-20200711062821-fab8125e9bdf/go.mod h1:95+K3z2L0mqsVYd6yveIv1lmtT3tcQQ3dVakPySffW8=
|
github.com/dsoprea/go-utility v0.0.0-20200711062821-fab8125e9bdf/go.mod h1:95+K3z2L0mqsVYd6yveIv1lmtT3tcQQ3dVakPySffW8=
|
||||||
|
github.com/dsoprea/go-utility v0.0.0-20221003172846-a3e1774ef349 h1:/py11NlxDaOxkT9OKN+gXgT+QOH5xj1ZRoyusfRIlo4=
|
||||||
|
github.com/dsoprea/go-utility v0.0.0-20221003172846-a3e1774ef349/go.mod h1:KVK+/Hul09ujXAGq+42UBgCTnXkiJZRnLYdURGjQUwo=
|
||||||
github.com/dsoprea/go-utility/v2 v2.0.0-20200717064901-2fccff4aa15e/go.mod h1:uAzdkPTub5Y9yQwXe8W4m2XuP0tK4a9Q/dantD0+uaU=
|
github.com/dsoprea/go-utility/v2 v2.0.0-20200717064901-2fccff4aa15e/go.mod h1:uAzdkPTub5Y9yQwXe8W4m2XuP0tK4a9Q/dantD0+uaU=
|
||||||
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||||
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||||
@@ -31,26 +34,28 @@ github.com/gen2brain/webp v0.5.0 h1:nn3o0BtKltoFKX9rlDZG/Y/aWqNzUZVyXdB815yVNfU=
|
|||||||
github.com/gen2brain/webp v0.5.0/go.mod h1:Nb3xO5sy6MeUAHhru9H3GT7nlOQO5dKRNNlE92CZrJw=
|
github.com/gen2brain/webp v0.5.0/go.mod h1:Nb3xO5sy6MeUAHhru9H3GT7nlOQO5dKRNNlE92CZrJw=
|
||||||
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
|
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
|
||||||
github.com/go-errors/errors v1.0.2/go.mod h1:psDX2osz5VnTOnFWbDeWwS7yejl+uV3FEWEp4lssFEs=
|
github.com/go-errors/errors v1.0.2/go.mod h1:psDX2osz5VnTOnFWbDeWwS7yejl+uV3FEWEp4lssFEs=
|
||||||
github.com/go-errors/errors v1.1.1 h1:ljK/pL5ltg3qoN+OtN6yCv9HWSfMwxSx90GJCZQxYNg=
|
|
||||||
github.com/go-errors/errors v1.1.1/go.mod h1:psDX2osz5VnTOnFWbDeWwS7yejl+uV3FEWEp4lssFEs=
|
github.com/go-errors/errors v1.1.1/go.mod h1:psDX2osz5VnTOnFWbDeWwS7yejl+uV3FEWEp4lssFEs=
|
||||||
|
github.com/go-errors/errors v1.5.1 h1:ZwEMSLRCapFLflTpT7NKaAc7ukJ8ZPEjzlxt8rPN8bk=
|
||||||
|
github.com/go-errors/errors v1.5.1/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
|
||||||
github.com/golang/geo v0.0.0-20190916061304-5b978397cfec/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI=
|
github.com/golang/geo v0.0.0-20190916061304-5b978397cfec/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI=
|
||||||
github.com/golang/geo v0.0.0-20200319012246-673a6f80352d h1:C/hKUcHT483btRbeGkrRjJz+Zbcj8audldIi9tRJDCc=
|
|
||||||
github.com/golang/geo v0.0.0-20200319012246-673a6f80352d/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI=
|
github.com/golang/geo v0.0.0-20200319012246-673a6f80352d/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI=
|
||||||
|
github.com/golang/geo v0.0.0-20230421003525-6adc56603217 h1:HKlyj6in2JV6wVkmQ4XmG/EIm+SCYlPZ+V4GWit7Z+I=
|
||||||
|
github.com/golang/geo v0.0.0-20230421003525-6adc56603217/go.mod h1:8wI0hitZ3a1IxZfeH3/5I97CI8i5cLGsYe7xNhQGs9U=
|
||||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||||
github.com/jupiterrider/ffi v0.2.1 h1:08GJVDqz4eoQq7cKT1T0kwb9MB58XEAGjgxDvz80yBs=
|
github.com/jupiterrider/ffi v0.2.1 h1:08GJVDqz4eoQq7cKT1T0kwb9MB58XEAGjgxDvz80yBs=
|
||||||
github.com/jupiterrider/ffi v0.2.1/go.mod h1:tJ7Q8p/3blFjdWt5qJU4W5oDE0xloImvrViE+0td0Rk=
|
github.com/jupiterrider/ffi v0.2.1/go.mod h1:tJ7Q8p/3blFjdWt5qJU4W5oDE0xloImvrViE+0td0Rk=
|
||||||
github.com/tetratelabs/wazero v1.8.1 h1:NrcgVbWfkWvVc4UtT4LRLDf91PsOzDzefMdwhLfA550=
|
github.com/tetratelabs/wazero v1.8.1 h1:NrcgVbWfkWvVc4UtT4LRLDf91PsOzDzefMdwhLfA550=
|
||||||
github.com/tetratelabs/wazero v1.8.1/go.mod h1:yAI0XTsMBhREkM/YDAK/zNou3GoiAce1P6+rp/wQhjs=
|
github.com/tetratelabs/wazero v1.8.1/go.mod h1:yAI0XTsMBhREkM/YDAK/zNou3GoiAce1P6+rp/wQhjs=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
|
||||||
golang.org/x/image v0.21.0 h1:c5qV36ajHpdj4Qi0GnE0jUc/yuo33OLFaa0d+crTD5s=
|
golang.org/x/image v0.21.0 h1:c5qV36ajHpdj4Qi0GnE0jUc/yuo33OLFaa0d+crTD5s=
|
||||||
golang.org/x/image v0.21.0/go.mod h1:vUbsLavqK/W303ZroQQVKQ+Af3Yl6Uz1Ppu5J/cLz78=
|
golang.org/x/image v0.21.0/go.mod h1:vUbsLavqK/W303ZroQQVKQ+Af3Yl6Uz1Ppu5J/cLz78=
|
||||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20200320220750-118fecf932d8/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20200320220750-118fecf932d8/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||||
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||||
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2 h1:eDrdRpKgkcCqKZQwyZRyeFZgfqt37SL7Kv3tok06cKE=
|
|
||||||
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||||
|
golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
|
||||||
|
golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
|
||||||
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
|
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
|
||||||
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
@@ -59,5 +64,6 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
|||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
|
||||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||||
|
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||||
|
Reference in New Issue
Block a user