mirror of
https://github.com/photoprism/photoprism.git
synced 2025-12-12 00:34:13 +01:00
This commit adds config parameters for thumbnail quality, max thumbnail size and geocoding api as well as a flag to to disable TensorFlow. Signed-off-by: Michael Mayer <michael@liquidbytes.net>
This commit is contained in:
@@ -55,6 +55,11 @@ func StartIndexing(router *gin.RouterGroup, conf *config.Config) {
|
||||
return
|
||||
}
|
||||
|
||||
// Set thumbnails JPEG quality and size
|
||||
photoprism.JpegQuality = conf.ThumbQuality()
|
||||
photoprism.MaxThumbWidth = conf.ThumbSize()
|
||||
photoprism.MaxThumbHeight = conf.ThumbSize()
|
||||
|
||||
path := conf.OriginalsPath()
|
||||
|
||||
event.Info(fmt.Sprintf("indexing photos in \"%s\"", filepath.Base(path)))
|
||||
|
||||
@@ -60,6 +60,7 @@ func configAction(ctx *cli.Context) error {
|
||||
fmt.Printf("resources-path %s\n", conf.ResourcesPath())
|
||||
fmt.Printf("tf-version %s\n", conf.TensorFlowVersion())
|
||||
fmt.Printf("tf-model-path %s\n", conf.TensorFlowModelPath())
|
||||
fmt.Printf("tf-disabled %t\n", conf.TensorFlowDisabled())
|
||||
fmt.Printf("templates-path %s\n", conf.HttpTemplatesPath())
|
||||
fmt.Printf("favicons-path %s\n", conf.HttpFaviconsPath())
|
||||
fmt.Printf("static-path %s\n", conf.HttpStaticPath())
|
||||
@@ -72,6 +73,9 @@ func configAction(ctx *cli.Context) error {
|
||||
|
||||
fmt.Printf("hide-nsfw %t\n", conf.HideNSFW())
|
||||
fmt.Printf("upload-nsfw %t\n", conf.UploadNSFW())
|
||||
fmt.Printf("geocoding-api %s\n", conf.GeoCodingApi())
|
||||
fmt.Printf("thumb-quality %d\n", conf.ThumbQuality())
|
||||
fmt.Printf("thumb-size %d\n", conf.ThumbSize())
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -32,6 +32,10 @@ func thumbnailsAction(ctx *cli.Context) error {
|
||||
|
||||
log.Infof("creating thumbnails in \"%s\"", conf.ThumbnailsPath())
|
||||
|
||||
photoprism.JpegQuality = conf.ThumbQuality()
|
||||
photoprism.MaxThumbWidth = conf.ThumbSize()
|
||||
photoprism.MaxThumbHeight = conf.ThumbSize()
|
||||
|
||||
if err := photoprism.CreateThumbnailsFromOriginals(conf.OriginalsPath(), conf.ThumbnailsPath(), ctx.Bool("force")); err != nil {
|
||||
log.Error(err)
|
||||
return err
|
||||
|
||||
@@ -11,7 +11,6 @@ import (
|
||||
gc "github.com/patrickmn/go-cache"
|
||||
"github.com/photoprism/photoprism/internal/event"
|
||||
"github.com/sirupsen/logrus"
|
||||
tensorflow "github.com/tensorflow/tensorflow/tensorflow/go"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
@@ -96,11 +95,6 @@ func (c *Config) Version() string {
|
||||
return c.config.Version
|
||||
}
|
||||
|
||||
// TensorFlowVersion returns the TenorFlow framework version.
|
||||
func (c *Config) TensorFlowVersion() string {
|
||||
return tensorflow.Version()
|
||||
}
|
||||
|
||||
// Copyright returns the application copyright.
|
||||
func (c *Config) Copyright() string {
|
||||
return c.config.Copyright
|
||||
@@ -185,3 +179,25 @@ func (c *Config) Shutdown() {
|
||||
func (c *Config) Workers() int {
|
||||
return runtime.NumCPU()
|
||||
}
|
||||
|
||||
// ThumbQuality returns the thumbnail jpeg quality setting (0-100).
|
||||
func (c *Config) ThumbQuality() int {
|
||||
return c.config.ThumbQuality
|
||||
}
|
||||
|
||||
// ThumbSize returns the thumbnail size limit in pixels.
|
||||
func (c *Config) ThumbSize() int {
|
||||
return c.config.ThumbSize
|
||||
}
|
||||
|
||||
|
||||
// GeoCodingApi returns the preferred geo coding api (none, osm or places).
|
||||
func (c *Config) GeoCodingApi() string {
|
||||
switch c.config.GeoCodingApi {
|
||||
case "places":
|
||||
return "places"
|
||||
case "osm":
|
||||
return "osm"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
@@ -214,4 +214,27 @@ var GlobalFlags = []cli.Flag{
|
||||
Usage: "allow uploads that may contain offensive content",
|
||||
EnvVar: "PHOTOPRISM_UPLOAD_NSFW",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "tf-disabled, t",
|
||||
Usage: "don't use TensorFlow for image classification",
|
||||
EnvVar: "PHOTOPRISM_TF_DISABLED",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "geocoding-api, g",
|
||||
Usage: "geocoding api (none, osm or places)",
|
||||
Value: "places",
|
||||
EnvVar: "PHOTOPRISM_GEOCODING_API",
|
||||
},
|
||||
cli.IntFlag{
|
||||
Name: "thumb-quality, q",
|
||||
Usage: "jpeg quality of thumbnails (0-100)",
|
||||
Value: 95,
|
||||
EnvVar: "PHOTOPRISM_THUMB_QUALITY",
|
||||
},
|
||||
cli.IntFlag{
|
||||
Name: "thumb-size",
|
||||
Usage: "max thumbnail size in pixels",
|
||||
Value: 8192,
|
||||
EnvVar: "PHOTOPRISM_THUMB_SIZE",
|
||||
},
|
||||
}
|
||||
|
||||
@@ -69,6 +69,10 @@ type Params struct {
|
||||
DetachServer bool `yaml:"detach-server" flag:"detach-server"`
|
||||
HideNSFW bool `yaml:"hide-nsfw" flag:"hide-nsfw"`
|
||||
UploadNSFW bool `yaml:"upload-nsfw" flag:"upload-nsfw"`
|
||||
DisableTensorFlow bool `yaml:"tf-disabled" flag:"tf-disabled"`
|
||||
GeoCodingApi string `yaml:"geocoding-api" flag:"geocoding-api"`
|
||||
ThumbQuality int `yaml:"thumb-quality" flag:"thumb-quality"`
|
||||
ThumbSize int `yaml:"thumb-size" flag:"thumb-size"`
|
||||
}
|
||||
|
||||
// NewParams() creates a new configuration entity by using two methods:
|
||||
|
||||
13
internal/config/tensorflow.go
Normal file
13
internal/config/tensorflow.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package config
|
||||
|
||||
import tf "github.com/tensorflow/tensorflow/tensorflow/go"
|
||||
|
||||
// TensorFlowVersion returns the TenorFlow framework version.
|
||||
func (c *Config) TensorFlowVersion() string {
|
||||
return tf.Version()
|
||||
}
|
||||
|
||||
// TensorFlowDisabled returns true if the use of TensorFlow is disabled for image classification.
|
||||
func (c *Config) TensorFlowDisabled() bool {
|
||||
return c.config.DisableTensorFlow
|
||||
}
|
||||
@@ -44,7 +44,7 @@ func NewLocation(lat, lng float64) *Location {
|
||||
return result
|
||||
}
|
||||
|
||||
func (m *Location) Find(db *gorm.DB) error {
|
||||
func (m *Location) Find(db *gorm.DB, api string) error {
|
||||
writeMutex.Lock()
|
||||
defer writeMutex.Unlock()
|
||||
|
||||
@@ -57,7 +57,7 @@ func (m *Location) Find(db *gorm.DB) error {
|
||||
ID: m.ID,
|
||||
}
|
||||
|
||||
if err := l.QueryPlaces(); err != nil {
|
||||
if err := l.Query(api); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
@@ -54,6 +54,17 @@ func NewLocation(id string) *Location {
|
||||
return result
|
||||
}
|
||||
|
||||
func (l *Location) Query(api string) error {
|
||||
switch api {
|
||||
case "osm":
|
||||
return l.QueryOSM()
|
||||
case "places":
|
||||
return l.QueryPlaces()
|
||||
}
|
||||
|
||||
return errors.New("maps: reverse lookup disabled")
|
||||
}
|
||||
|
||||
func (l *Location) QueryPlaces() error {
|
||||
s, err := places.FindLocation(l.ID)
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ func (ind *Index) MediaFile(m *MediaFile, o IndexOptions) IndexResult {
|
||||
photo.PhotoName = fileBase
|
||||
|
||||
if file.FilePrimary {
|
||||
if fileChanged || o.UpdateKeywords || o.UpdateLabels || o.UpdateTitle {
|
||||
if !ind.conf.TensorFlowDisabled() && (fileChanged || o.UpdateKeywords || o.UpdateLabels || o.UpdateTitle) {
|
||||
// Image classification labels
|
||||
labels, isNSFW = ind.classifyImage(m)
|
||||
photo.PhotoNSFW = isNSFW
|
||||
@@ -368,10 +368,10 @@ func (ind *Index) indexLocation(mediaFile *MediaFile, photo *entity.Photo, label
|
||||
location.Lock()
|
||||
defer location.Unlock()
|
||||
|
||||
err := location.Find(ind.db)
|
||||
err := location.Find(ind.db, ind.conf.GeoCodingApi())
|
||||
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
log.Warn(err)
|
||||
return keywords, labels
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ func TestMediaFile_Location(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err = location.Find(conf.Db()); err != nil {
|
||||
if err = location.Find(conf.Db(), "places"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ func TestMediaFile_Location(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err = location.Find(conf.Db()); err != nil {
|
||||
if err = location.Find(conf.Db(), "places"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ func TestMediaFile_Location(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err = location.Find(conf.Db()); err != nil {
|
||||
if err = location.Find(conf.Db(), "places"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
|
||||
@@ -47,6 +47,10 @@ func NewTensorFlow(conf *config.Config) *TensorFlow {
|
||||
}
|
||||
|
||||
func (t *TensorFlow) Init() (err error) {
|
||||
if t.conf.TensorFlowDisabled() {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := t.loadModel(); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -85,6 +89,10 @@ func (t *TensorFlow) loadLabelRules() (err error) {
|
||||
|
||||
// LabelsFromFile returns matching labels for a jpeg media file.
|
||||
func (t *TensorFlow) LabelsFromFile(filename string) (result Labels, err error) {
|
||||
if t.conf.TensorFlowDisabled() {
|
||||
return result, nil
|
||||
}
|
||||
|
||||
imageBuffer, err := ioutil.ReadFile(filename)
|
||||
|
||||
if err != nil {
|
||||
@@ -96,6 +104,10 @@ func (t *TensorFlow) LabelsFromFile(filename string) (result Labels, err error)
|
||||
|
||||
// Labels returns matching labels for a jpeg media string.
|
||||
func (t *TensorFlow) Labels(img []byte) (result Labels, err error) {
|
||||
if t.conf.TensorFlowDisabled() {
|
||||
return result, nil
|
||||
}
|
||||
|
||||
if err := t.loadModel(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ import (
|
||||
"github.com/photoprism/photoprism/internal/util"
|
||||
)
|
||||
|
||||
const (
|
||||
var (
|
||||
MaxThumbWidth = 8192
|
||||
MaxThumbHeight = 8192
|
||||
JpegQuality = 95
|
||||
@@ -317,6 +317,11 @@ func (m *MediaFile) CreateDefaultThumbnails(thumbPath string, force bool) (err e
|
||||
for _, name := range DefaultThumbnails {
|
||||
thumbType := ThumbnailTypes[name]
|
||||
|
||||
if thumbType.Height > MaxThumbHeight || thumbType.Width > MaxThumbWidth {
|
||||
log.Debugf("thumbs: size exceeds limit (width %d, height %d)", thumbType.Width, thumbType.Height)
|
||||
continue
|
||||
}
|
||||
|
||||
if fileName, err := ThumbnailFilename(hash, thumbPath, thumbType.Width, thumbType.Height, thumbType.Options...); err != nil {
|
||||
log.Errorf("could not create %s thumbnail: \"%s\"", name, err)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user