You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
caddy-hugo2/media/thumb.go

111 lines
2.2 KiB

package media
import (
"fmt"
"image"
"io"
"os"
"path"
"path/filepath"
)
func (ms *MediaSource) ThumbPath(m Media, size image.Rectangle) string {
size = m.NormalizeSize(size)
return thumbPath(size, m.Name)
}
func (ms *MediaSource) ThumbFilename(m Media, size image.Rectangle) string {
size = m.NormalizeSize(size)
return thumbFilename(ms.ThumbDir, size, m.Name)
}
func thumbFilename(dir string, size image.Rectangle, name string) string {
return filepath.Join(dir, thumbPath(size, name))
}
func thumbPath(size image.Rectangle, name string) string {
w := size.Dx()
h := size.Dy()
var ws, hs string
if w != 0 {
ws = fmt.Sprint(w)
}
if h != 0 {
hs = fmt.Sprint(h)
}
thumbSlug := filepath.Join(fmt.Sprintf("%sx%s", ws, hs), name)
return path.Join("", "media", thumbSlug)
}
func (ms *MediaSource) ThumbMax(m Media, maxDim int) (image.Rectangle, error) {
width := m.Size.Dx()
height := m.Size.Dy()
if width == 0 && height == 0 {
return m.Size, fmt.Errorf("invalid media")
}
if width > height {
height = height * maxDim / width
width = maxDim
} else {
width = width * maxDim / height
height = maxDim
}
size := image.Rect(0, 0, width, height)
actual, err := ms.Thumb(m, size)
return actual, err
}
func (ms *MediaSource) HasThumb(m Media, size image.Rectangle) bool {
fi, err := os.Stat(ms.ThumbFilename(m, size))
if err != nil {
return false
}
return m.Date().Before(fi.ModTime())
}
func (m Media) NormalizeSize(size image.Rectangle) image.Rectangle {
return NormalizeSize(m.Size, size)
}
func (ms *MediaSource) Thumb(m Media, size image.Rectangle) (image.Rectangle, error) {
size = m.NormalizeSize(size)
if ms.HasThumb(m, size) {
return size, nil
}
f, err := os.Open(m.FullName)
if err != nil {
return size, err
}
defer f.Close()
return size, ms.thumbReader(f, m, size)
}
func (ms *MediaSource) thumbReader(r io.Reader, m Media, size image.Rectangle) error {
size = m.NormalizeSize(size)
switch m.Type {
case TypeImage:
img, _, err := image.Decode(r)
if err != nil {
return err
}
filename := ms.ThumbFilename(m, size)
return ThumbImage(filename, img, size)
case TypeVideo:
return VideoEncode(m.FullName, size, ms.ThumbDir)
default:
return fmt.Errorf("cannot thumb media type %q", m.Type)
}
}