mirror of
https://git.vectorsigma.ru/public/photoview.git
synced 2026-08-03 21:09:05 +00:00
Add blurhash generation
This commit is contained in:
98
api/scanner/thumbnail_blurhash.go
Normal file
98
api/scanner/thumbnail_blurhash.go
Normal file
@@ -0,0 +1,98 @@
|
||||
package scanner
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"image"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/buckket/go-blurhash"
|
||||
"github.com/photoview/photoview/api/graphql/models"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// GenerateBlurhashes queries the database for media that are missing a blurhash and computes one for them.
|
||||
// This function blocks until all hashes have been computed
|
||||
func GenerateBlurhashes(db *gorm.DB) error {
|
||||
var results []*models.Media
|
||||
|
||||
processErrors := make([]error, 0)
|
||||
|
||||
query := db.Model(&models.Media{}).
|
||||
Preload("MediaURL").
|
||||
Joins("INNER JOIN media_urls ON media.id = media_urls.media_id").
|
||||
Where("blurhash IS NULL").
|
||||
Where("media_urls.purpose = 'thumbnail' OR media_urls.purpose = 'video-thumbnail'")
|
||||
|
||||
err := query.FindInBatches(&results, 100, func(tx *gorm.DB, batch int) error {
|
||||
log.Printf("generating %d blurhashes", len(results))
|
||||
|
||||
hashes := make([]*string, len(results))
|
||||
|
||||
for i, row := range results {
|
||||
|
||||
thumbnail, err := row.Thumbnail()
|
||||
if err != nil {
|
||||
log.Printf("failed to get thumbnail for media to generate blurhash (%d): %v", row.ID, err)
|
||||
processErrors = append(processErrors, err)
|
||||
continue
|
||||
}
|
||||
|
||||
hashStr, err := GenerateBlurhashFromThumbnail(thumbnail)
|
||||
if err != nil {
|
||||
log.Printf("failed to generate blurhash for media (%d): %v", row.ID, err)
|
||||
processErrors = append(processErrors, err)
|
||||
continue
|
||||
}
|
||||
|
||||
hashes[i] = &hashStr
|
||||
results[i].Blurhash = &hashStr
|
||||
}
|
||||
|
||||
tx.Save(results)
|
||||
// if err := db.Update("blurhash", hashes).Error; err != nil {
|
||||
// return err
|
||||
// }
|
||||
|
||||
return nil
|
||||
}).Error
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(processErrors) == 0 {
|
||||
return nil
|
||||
} else {
|
||||
return fmt.Errorf("failed to generate %d blurhashes", len(processErrors))
|
||||
}
|
||||
}
|
||||
|
||||
// GenerateBlurhashFromThumbnail generates a blurhash for a single media and stores it in the database
|
||||
func GenerateBlurhashFromThumbnail(thumbnail *models.MediaURL) (string, error) {
|
||||
thumbnail_path, err := thumbnail.CachedPath()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
imageFile, err := os.Open(thumbnail_path)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
imageData, _, err := image.Decode(imageFile)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
hashStr, err := blurhash.Encode(4, 3, imageData)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// if err := db.Model(&models.Media{}).Where("id = ?", thumbnail.MediaID).Update("blurhash", hashStr).Error; err != nil {
|
||||
// return "", err
|
||||
// }
|
||||
|
||||
return hashStr, nil
|
||||
}
|
||||
Reference in New Issue
Block a user