Live Photos: Show correct image and video dimensions #3559

Signed-off-by: Michael Mayer <michael@photoprism.app>
This commit is contained in:
Michael Mayer 2023-08-15 14:51:32 +02:00
parent 5822a26b8c
commit 3f6cb27497
4 changed files with 54 additions and 30 deletions

View file

@ -203,6 +203,11 @@
<i>movie</i>
{{ photo.getVideoInfo() }}
</button>
<button v-else-if="photo.Type === 'live'" :title="$gettext('Live')"
@click.exact="openPhoto(index)">
<i>phone_iphone</i>
{{ photo.getPhotoInfo() }}
</button>
<button v-else-if="photo.Type === 'animated'" :title="$gettext('Animated')+' GIF'"
@click.exact="openPhoto(index)">
<i>gif_box</i>

View file

@ -851,11 +851,7 @@ export class Photo extends RestModel {
});
getPhotoInfo = () => {
let file = this.videoFile();
if (!file || !file.Width) {
file = this.mainFile();
}
let file = this.mainFile() || this.videoFile();
return this.generatePhotoInfo(this.Camera, this.CameraModel, this.CameraMake, file);
};

View file

@ -64,13 +64,13 @@ type File struct {
FileVideo bool `json:"Video" yaml:"Video,omitempty"`
FileDuration time.Duration `json:"Duration" yaml:"Duration,omitempty"`
FileFPS float64 `gorm:"column:file_fps;" json:"FPS" yaml:"FPS,omitempty"`
FileFrames int `json:"Frames" yaml:"Frames,omitempty"`
FileWidth int `json:"Width" yaml:"Width,omitempty"`
FileHeight int `json:"Height" yaml:"Height,omitempty"`
FileOrientation int `json:"Orientation" yaml:"Orientation,omitempty"`
FileOrientationSrc string `gorm:"type:VARBINARY(8);default:'';" json:"OrientationSrc" yaml:"OrientationSrc,omitempty"`
FileProjection string `gorm:"type:VARBINARY(64);" json:"Projection,omitempty" yaml:"Projection,omitempty"`
FileAspectRatio float32 `gorm:"type:FLOAT;" json:"AspectRatio" yaml:"AspectRatio,omitempty"`
FileFrames int `gorm:"column:file_frames;" json:"Frames" yaml:"Frames,omitempty"`
FileWidth int `gorm:"column:file_width;" json:"Width" yaml:"Width,omitempty"`
FileHeight int `gorm:"column:file_height;" json:"Height" yaml:"Height,omitempty"`
FileOrientation int `gorm:"column:file_orientation;" json:"Orientation" yaml:"Orientation,omitempty"`
FileOrientationSrc string `gorm:"column:file_orientation_src;type:VARBINARY(8);default:'';" json:"OrientationSrc" yaml:"OrientationSrc,omitempty"`
FileProjection string `gorm:"column:file_projection;type:VARBINARY(64);" json:"Projection,omitempty" yaml:"Projection,omitempty"`
FileAspectRatio float32 `gorm:"column:file_aspect_ratio;type:FLOAT;" json:"AspectRatio" yaml:"AspectRatio,omitempty"`
FileHDR bool `gorm:"column:file_hdr;" json:"HDR" yaml:"HDR,omitempty"`
FileWatermark bool `gorm:"column:file_watermark;" json:"Watermark" yaml:"Watermark,omitempty"`
FileColorProfile string `gorm:"type:VARBINARY(64);" json:"ColorProfile,omitempty" yaml:"ColorProfile,omitempty"`
@ -156,18 +156,6 @@ func (m File) RegenerateIndex() {
log.Debugf("search: updated %s [%s]", scope, time.Since(start))
}
type FileInfos struct {
FileWidth int
FileHeight int
FileOrientation int
FileAspectRatio float32
FileMainColor string
FileColors string
FileLuminance string
FileDiff int
FileChroma int16
}
// FirstFileByHash gets a file in db from its hash
func FirstFileByHash(fileHash string) (File, error) {
var file File
@ -460,13 +448,44 @@ func (m *File) Save() error {
// UpdateVideoInfos updates related video infos based on this file.
func (m *File) UpdateVideoInfos() error {
values := FileInfos{}
if m.PhotoID <= 0 {
return fmt.Errorf("file has invalid photo id")
}
if err := deepcopier.Copy(&values).From(m); err != nil {
// Update video dimensions, if necessary.
type Dimensions struct {
FileWidth int
FileHeight int
FileOrientation int
FileAspectRatio float32
}
dimensions := Dimensions{}
if err := deepcopier.Copy(&dimensions).From(m); err != nil {
return err
} else if err = Db().Model(File{}).Where("photo_id = ? AND file_video = 1 AND file_width <= 0", m.PhotoID).Updates(dimensions).Error; err != nil {
return err
}
return Db().Model(File{}).Where("photo_id = ? AND file_video = 1", m.PhotoID).Updates(values).Error
// Update video appearance, if necessary.
type Appearance struct {
FileMainColor string
FileColors string
FileLuminance string
FileDiff int
FileChroma int16
}
appearance := Appearance{}
if err := deepcopier.Copy(&appearance).From(m); err != nil {
return err
} else if err = Db().Model(File{}).Where("photo_id = ? AND file_video = 1 AND file_diff <= 0", m.PhotoID).Updates(appearance).Error; err != nil {
return err
}
return nil
}
// Update updates a column in the database.

View file

@ -648,6 +648,8 @@ func (ind *Index) UserMediaFile(m *MediaFile, o IndexOptions, originalName, phot
}
}
// Set video dimensions from primary file, if necessary.
// See also File.UpdateVideoInfos()
if file.FileWidth == 0 && primaryFile.FileWidth > 0 {
file.FileWidth = primaryFile.FileWidth
file.FileHeight = primaryFile.FileHeight
@ -655,12 +657,14 @@ func (ind *Index) UserMediaFile(m *MediaFile, o IndexOptions, originalName, phot
file.FilePortrait = primaryFile.FilePortrait
}
// Set video appearance from primary file, if necessary.
// See also File.UpdateVideoInfos()
if primaryFile.FileDiff > 0 {
file.FileDiff = primaryFile.FileDiff
file.FileMainColor = primaryFile.FileMainColor
file.FileChroma = primaryFile.FileChroma
file.FileLuminance = primaryFile.FileLuminance
file.FileColors = primaryFile.FileColors
file.FileLuminance = primaryFile.FileLuminance
file.FileDiff = primaryFile.FileDiff
file.FileChroma = primaryFile.FileChroma
}
}