126 lines
2.8 KiB
Go
126 lines
2.8 KiB
Go
package bucket
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"mime"
|
|
"strings"
|
|
)
|
|
|
|
type Preview string
|
|
|
|
const previewPrefix = "preview/"
|
|
|
|
var ErrorInvalidPreview = errors.New("invalid preview")
|
|
|
|
func (p Preview) Validate() error {
|
|
if !strings.HasPrefix(string(p), previewPrefix) {
|
|
return fmt.Errorf("%w: %v", ErrorInvalidPreview, p)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (p Preview) String() string {
|
|
return string(p)
|
|
}
|
|
|
|
func (p Preview) Format() PhotoFormat {
|
|
extIndex := strings.LastIndex(string(p), ".")
|
|
return PhotoFormat(mime.TypeByExtension(string(p)[extIndex:]))
|
|
}
|
|
|
|
type PreviewOption struct {
|
|
Height int
|
|
//Width int
|
|
Format PhotoFormat
|
|
Quality int
|
|
}
|
|
|
|
type PhotoFormat string
|
|
|
|
const (
|
|
PhotoFormatJPEG PhotoFormat = "image/jpeg"
|
|
PhotoFormatWEBP PhotoFormat = "image/webp"
|
|
PhotoFormatHEIF PhotoFormat = "image/heif"
|
|
PhotoFormatPNG PhotoFormat = "image/png"
|
|
PhotoFormatGIF PhotoFormat = "image/gif"
|
|
PhotoFormatTIFF PhotoFormat = "image/tiff"
|
|
)
|
|
|
|
func (f PhotoFormat) ContentType() string {
|
|
return string(f)
|
|
}
|
|
|
|
var SupportedFormats = []PhotoFormat{
|
|
PhotoFormatJPEG,
|
|
PhotoFormatWEBP,
|
|
PhotoFormatHEIF,
|
|
PhotoFormatPNG,
|
|
PhotoFormatGIF,
|
|
PhotoFormatTIFF,
|
|
}
|
|
|
|
type PhotoQualityLevel int
|
|
|
|
const (
|
|
PhotoQualityLevelThumbnail PhotoQualityLevel = 0
|
|
PhotoQualityLevelBasic PhotoQualityLevel = 1
|
|
PhotoQualityLevelNormal PhotoQualityLevel = 2
|
|
PhotoQualityLevelExtreme PhotoQualityLevel = 3
|
|
)
|
|
|
|
func (f PhotoFormat) Quality(level PhotoQualityLevel) int {
|
|
if f == PhotoFormatJPEG || f == PhotoFormatWEBP {
|
|
return 34 + int(level)*18
|
|
}
|
|
if f == PhotoFormatHEIF {
|
|
return 10 + int(level)*10
|
|
}
|
|
return 0
|
|
}
|
|
|
|
func (p Photo) GetPreview(option PreviewOption) Preview {
|
|
objectBase := strings.Replace(string(p), photoPrefix, previewPrefix, 1)
|
|
extIndex := strings.LastIndex(objectBase, ".")
|
|
base := objectBase[:extIndex]
|
|
res := fmt.Sprintf("_h%dq%d", option.Height, option.Quality)
|
|
exts, err := mime.ExtensionsByType(option.Format.ContentType())
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
if len(exts) < 1 {
|
|
panic("missing MIME type to extension mapping, please configure within your operating system")
|
|
}
|
|
return Preview(base + res + exts[0])
|
|
}
|
|
|
|
var defaultSizes = []int{640, 320, 160, 80}
|
|
var defaultSizesThumb = []int{60, 30}
|
|
var defaultFormats = []PhotoFormat{
|
|
PhotoFormatWEBP,
|
|
PhotoFormatJPEG,
|
|
}
|
|
|
|
func DefaultPreviewOptions() []PreviewOption {
|
|
options := make([]PreviewOption, 0)
|
|
for _, size := range defaultSizes {
|
|
for _, format := range defaultFormats {
|
|
options = append(options, PreviewOption{
|
|
Height: size,
|
|
Format: format,
|
|
Quality: format.Quality(PhotoQualityLevelNormal),
|
|
})
|
|
}
|
|
}
|
|
for _, size := range defaultSizesThumb {
|
|
for _, format := range defaultFormats {
|
|
options = append(options, PreviewOption{
|
|
Height: size,
|
|
Format: format,
|
|
Quality: format.Quality(PhotoQualityLevelThumbnail),
|
|
})
|
|
}
|
|
}
|
|
return options
|
|
}
|