114 lines
2.9 KiB
Go
114 lines
2.9 KiB
Go
package photoprism
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
|
|
"github.com/photoprism/photoprism/internal/config"
|
|
)
|
|
|
|
// Converter wraps a darktable cli binary.
|
|
type Converter struct {
|
|
conf *config.Config
|
|
}
|
|
|
|
// NewConverter returns a new converter by setting the darktable
|
|
// cli binary location.
|
|
func NewConverter(conf *config.Config) *Converter {
|
|
return &Converter{conf: conf}
|
|
}
|
|
|
|
// ConvertAll converts all the files given a path to JPEG. This function
|
|
// ignores error during this process.
|
|
func (c *Converter) ConvertAll(path string) {
|
|
err := filepath.Walk(path, func(filename string, fileInfo os.FileInfo, err error) error {
|
|
|
|
if err != nil {
|
|
log.Error("Walk", err.Error())
|
|
return nil
|
|
}
|
|
|
|
if fileInfo.IsDir() {
|
|
return nil
|
|
}
|
|
|
|
mediaFile, err := NewMediaFile(filename)
|
|
|
|
if err != nil || !(mediaFile.IsRaw() || mediaFile.IsHEIF()) {
|
|
return nil
|
|
}
|
|
|
|
if _, err := c.ConvertToJpeg(mediaFile); err != nil {
|
|
log.Warnf("file could not be converted to JPEG: \"%s\"", filename)
|
|
}
|
|
|
|
return nil
|
|
})
|
|
|
|
if err != nil {
|
|
log.Error(err.Error())
|
|
}
|
|
}
|
|
|
|
func (c *Converter) ConvertCommand(image *MediaFile, jpegFilename string, xmpFilename string) (result *exec.Cmd, err error) {
|
|
if image.IsRaw() {
|
|
if c.conf.SipsBin() != "" {
|
|
result = exec.Command(c.conf.SipsBin(), "-s format jpeg", image.filename, "--out "+jpegFilename)
|
|
} else if c.conf.DarktableBin() != "" && xmpFilename != "" {
|
|
result = exec.Command(c.conf.DarktableBin(), image.filename, xmpFilename, jpegFilename)
|
|
} else if c.conf.DarktableBin() != "" {
|
|
result = exec.Command(c.conf.DarktableBin(), image.filename, jpegFilename)
|
|
} else {
|
|
return nil, fmt.Errorf("no binary for raw to jpeg conversion could be found: %s", image.Filename())
|
|
}
|
|
} else if image.IsHEIF() {
|
|
result = exec.Command(c.conf.HeifConvertBin(), image.filename, jpegFilename)
|
|
} else {
|
|
return nil, fmt.Errorf("image type not supported for conversion: %s", image.Type())
|
|
}
|
|
|
|
return result, nil
|
|
}
|
|
|
|
// ConvertToJpeg converts a single image the JPEG format.
|
|
func (c *Converter) ConvertToJpeg(image *MediaFile) (*MediaFile, error) {
|
|
if !image.Exists() {
|
|
return nil, fmt.Errorf("can not convert to jpeg, file does not exist: %s", image.Filename())
|
|
}
|
|
|
|
if image.IsJpeg() {
|
|
return image, nil
|
|
}
|
|
|
|
baseFilename := image.DirectoryBasename()
|
|
|
|
jpegFilename := baseFilename + ".jpg"
|
|
|
|
mediaFile, err := NewMediaFile(jpegFilename)
|
|
|
|
if err == nil {
|
|
return mediaFile, nil
|
|
}
|
|
|
|
if c.conf.ReadOnly() {
|
|
return nil, fmt.Errorf("can not convert to jpeg in read only mode: %s", image.Filename())
|
|
}
|
|
|
|
log.Infof("converting \"%s\" to \"%s\"", image.filename, jpegFilename)
|
|
|
|
xmpFilename := baseFilename + ".xmp"
|
|
|
|
if _, err := os.Stat(xmpFilename); err != nil {
|
|
xmpFilename = ""
|
|
}
|
|
|
|
if convertCommand, err := c.ConvertCommand(image, jpegFilename, xmpFilename); err != nil {
|
|
return nil, err
|
|
} else if err := convertCommand.Run(); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return NewMediaFile(jpegFilename)
|
|
}
|