107 lines
2.3 KiB
Go
107 lines
2.3 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"bufio"
|
||
|
"fmt"
|
||
|
"image"
|
||
|
"io/fs"
|
||
|
"os"
|
||
|
"slices"
|
||
|
"strings"
|
||
|
"sync"
|
||
|
|
||
|
"fyne.io/fyne/v2/data/binding"
|
||
|
"github.com/disintegration/imaging"
|
||
|
"github.com/pixiv/go-libwebp/webp"
|
||
|
"github.com/rwcarlsen/goexif/tiff"
|
||
|
"golang.org/x/image/draw"
|
||
|
)
|
||
|
|
||
|
func convertRange(inputPath, outputPath string, files []fs.DirEntry, threads, mod int, progress binding.Float, unconverted binding.StringList, wg *sync.WaitGroup) {
|
||
|
defer wg.Done()
|
||
|
|
||
|
for i, file := range files {
|
||
|
if i%threads == mod {
|
||
|
if err := convert(inputPath, outputPath, file); err != nil {
|
||
|
unconverted.Append(file.Name())
|
||
|
}
|
||
|
|
||
|
p, _ := progress.Get()
|
||
|
progress.Set((p*float64(len(files)) + 1) / float64(len(files)))
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func convert(inputPath, outputPath string, file fs.DirEntry) error {
|
||
|
name := file.Name()
|
||
|
parts := strings.Split(name, ".")
|
||
|
ext := strings.ToLower(parts[len(parts)-1])
|
||
|
if !file.Type().IsRegular() || !slices.Contains(supported, ext) {
|
||
|
return fmt.Errorf("file type %s is not supported", ext)
|
||
|
}
|
||
|
|
||
|
img, orientation, err := ReadIMG(fmt.Sprintf("%s/%s", inputPath, name))
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
dest, err := rotate(scale(img), orientation)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
io, err := os.Create(fmt.Sprintf("%s/%swebp", outputPath, strings.TrimSuffix(name, ext)))
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
wr := bufio.NewWriter(io)
|
||
|
defer func() {
|
||
|
wr.Flush()
|
||
|
io.Close()
|
||
|
}()
|
||
|
|
||
|
config, err := webp.ConfigPreset(webp.PresetDefault, 75)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
config.SetAlphaQuality(100)
|
||
|
config.SetMethod(4)
|
||
|
config.SetSegments(4)
|
||
|
config.SetSNSStrength(50)
|
||
|
config.SetFilterStrength(60)
|
||
|
config.SetFilterSharpness(0)
|
||
|
|
||
|
err = webp.EncodeRGBA(wr, dest, config)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func scale(img image.Image) (dest *image.NRGBA) {
|
||
|
b := img.Bounds()
|
||
|
factor := float32(b.Max.X) / float32(b.Max.Y)
|
||
|
dest = image.NewNRGBA(image.Rect(0, 0, int(factor*1440), 1440))
|
||
|
draw.ApproxBiLinear.Scale(dest, dest.Rect, img, b, draw.Over, nil)
|
||
|
return dest
|
||
|
}
|
||
|
|
||
|
func rotate(img image.Image, orientation *tiff.Tag) (dest *image.NRGBA, err error) {
|
||
|
rotate, err := orientation.Int(0)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
switch rotate {
|
||
|
case 3:
|
||
|
dest = imaging.Rotate180(img)
|
||
|
case 6:
|
||
|
dest = imaging.Rotate270(img)
|
||
|
case 8:
|
||
|
dest = imaging.Rotate90(img)
|
||
|
}
|
||
|
|
||
|
return dest, nil
|
||
|
}
|