feat: add image resolution display

This commit is contained in:
MAERYO 2023-11-15 22:42:22 +09:00
parent d59ad594b8
commit 0f2835fbb6
3 changed files with 68 additions and 4 deletions

View File

@ -6,7 +6,9 @@ import (
"crypto/sha256"
"crypto/sha512"
"encoding/hex"
"github.com/spf13/afero"
"hash"
"image"
"io"
"log"
"mime"
@ -17,8 +19,6 @@ import (
"strings"
"time"
"github.com/spf13/afero"
"github.com/filebrowser/filebrowser/v2/errors"
"github.com/filebrowser/filebrowser/v2/rules"
)
@ -44,6 +44,7 @@ type FileInfo struct {
Checksums map[string]string `json:"checksums,omitempty"`
Token string `json:"token,omitempty"`
currentDir []os.FileInfo `json:"-"`
Resolution *ImageResolution `json:"resolution,omitempty"`
}
// FileOptions are the options when getting a file info.
@ -58,6 +59,11 @@ type FileOptions struct {
Content bool
}
type ImageResolution struct {
Width int `json:"width"`
Height int `json:"height"`
}
// NewFileInfo creates a File object from a path and a given user. This File
// object will be automatically filled depending on if it is a directory
// or a file. If it's a video file, it will also detect any subtitles.
@ -234,8 +240,14 @@ func (i *FileInfo) detectType(modify, saveContent, readHeader bool) error {
case strings.HasPrefix(mimetype, "audio"):
i.Type = "audio"
return nil
case strings.HasPrefix(mimetype, "image"):
case strings.HasPrefix(mimetype, "image"), strings.HasPrefix(mimetype, "video"):
i.Type = "image"
resolution, err := calculateImageResolution(i.Fs, i.Path)
if err != nil {
log.Printf("Error calculating image resolution: %v", err)
} else {
i.Resolution = resolution
}
return nil
case strings.HasSuffix(mimetype, "pdf"):
i.Type = "pdf"
@ -264,6 +276,29 @@ func (i *FileInfo) detectType(modify, saveContent, readHeader bool) error {
return nil
}
func calculateImageResolution(fs afero.Fs, path string) (*ImageResolution, error) {
file, err := fs.Open(path)
if err != nil {
return nil, err
}
defer func(file afero.File) {
err := file.Close()
if err != nil {
}
}(file)
config, _, err := image.DecodeConfig(file)
if err != nil {
return nil, err
}
return &ImageResolution{
Width: config.Width,
Height: config.Height,
}, nil
}
func (i *FileInfo) readFirstBytes() []byte {
reader, err := i.Fs.Open(i.Path)
if err != nil {
@ -361,6 +396,15 @@ func (i *FileInfo) readListing(checker rules.Checker, readHeader bool) error {
currentDir: dir,
}
if !file.IsDir && strings.HasPrefix(mime.TypeByExtension(file.Extension), "image/") {
resolution, err := calculateImageResolution(file.Fs, file.Path)
if err != nil {
log.Printf("Error calculating resolution for image %s: %v", file.Path, err)
} else {
file.Resolution = resolution
}
}
if file.IsDir {
listing.NumDirs++
} else {

View File

@ -12,10 +12,17 @@
<p class="break-word" v-if="selected.length < 2">
<strong>{{ $t("prompts.displayName") }}</strong> {{ name }}
</p>
<p v-if="!dir || selected.length > 1">
<strong>{{ $t("prompts.size") }}:</strong>
<span id="content_length"></span> {{ humanSize }}
</p>
<div v-if="resolution">
<strong>{{ $t("prompts.resolution") }}:</strong>
{{ resolution.width }} x {{ resolution.height }}
</div>
<p v-if="selected.length < 2" :title="modTime">
<strong>{{ $t("prompts.lastModified") }}:</strong> {{ humanTime }}
</p>
@ -126,6 +133,18 @@ export default {
: this.req.items[this.selected[0]].isDir)
);
},
resolution: function() {
if (this.selectedCount === 1) {
const selectedItem = this.req.items[this.selected[0]];
if (selectedItem && selectedItem.type === 'image') {
return selectedItem.resolution;
}
}
else if (this.req && this.req.type === 'image') {
return this.req.resolution;
}
return null;
},
},
methods: {
checksum: async function (event, algo) {

View File

@ -161,7 +161,8 @@
"upload": "Upload",
"uploadFiles": "Uploading {files} files...",
"uploadMessage": "Select an option to upload.",
"optionalPassword": "Optional password"
"optionalPassword": "Optional password",
"resolution": "Resolution"
},
"search": {
"images": "Images",