initial commit
This commit is contained in:
106
convert.go
Normal file
106
convert.go
Normal file
@ -0,0 +1,106 @@
|
||||
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
|
||||
}
|
Reference in New Issue
Block a user