From 5cee5d8dea847db66ea33d8b786baabb73d7692f Mon Sep 17 00:00:00 2001 From: viktorstrate Date: Mon, 2 Mar 2020 16:32:24 +0100 Subject: [PATCH] Add TIFF support, this closes #3 --- api/scanner/album_scanner.go | 3 +-- api/scanner/process_photo.go | 29 ++++++++++++++++++++++++----- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/api/scanner/album_scanner.go b/api/scanner/album_scanner.go index c51eaefd..869a2576 100644 --- a/api/scanner/album_scanner.go +++ b/api/scanner/album_scanner.go @@ -272,8 +272,7 @@ func directoryContainsPhotos(rootPath string, cache *scanner_cache) bool { var SupportedMimetypes = [...]string{ "image/jpeg", "image/png", - // todo: add support for tiff - // "image/tiff", + "image/tiff", "image/webp", "image/x-canon-cr2", "image/bmp", diff --git a/api/scanner/process_photo.go b/api/scanner/process_photo.go index e2086622..1726879e 100644 --- a/api/scanner/process_photo.go +++ b/api/scanner/process_photo.go @@ -17,13 +17,14 @@ import ( "github.com/viktorstrate/photoview/api/utils" // Image decoders - _ "golang.org/x/image/bmp" - // _ "golang.org/x/image/tiff" _ "image/gif" _ "image/png" - _ "github.com/nf/cr2" + _ "golang.org/x/image/bmp" + _ "golang.org/x/image/tiff" _ "golang.org/x/image/webp" + + cr2Decoder "github.com/nf/cr2" ) // Higher order function used to check if PhotoURL for a given PhotoPurpose exists @@ -261,6 +262,7 @@ func encodeImageJPEG(photoPath string, photoImage image.Image, jpegOptions *jpeg return nil } +// ProcessImageData is used to easily decode image data, with a cache so expensive operations are not repeated type ProcessImageData struct { photoPath string _photoImage image.Image @@ -268,6 +270,7 @@ type ProcessImageData struct { _contentType *string } +// ContentType reads the image to determine its content type func (img *ProcessImageData) ContentType() (*string, error) { if img._contentType != nil { return img._contentType, nil @@ -295,6 +298,7 @@ func (img *ProcessImageData) ContentType() (*string, error) { return img._contentType, nil } +// PhotoImage reads and decodes the image file and saves it in a cache so the photo in only decoded once func (img *ProcessImageData) PhotoImage() (image.Image, error) { if img._photoImage != nil { return img._photoImage, nil @@ -306,16 +310,31 @@ func (img *ProcessImageData) PhotoImage() (image.Image, error) { } defer photoFile.Close() - photoImg, _, err := image.Decode(photoFile) + var photoImg image.Image + contentType, err := img.ContentType() if err != nil { - log.Println("ERROR: decoding image") return nil, err } + if contentType != nil && *contentType == "image/x-canon-cr2" { + photoImg, err = cr2Decoder.Decode(photoFile) + if err != nil { + log.Println("ERROR: decoding cr2 raw image") + return nil, err + } + } else { + photoImg, _, err = image.Decode(photoFile) + if err != nil { + log.Println("ERROR: decoding image") + return nil, err + } + } + img._photoImage = photoImg return img._photoImage, nil } +// ThumbnailImage downsizes the image and returns it func (img *ProcessImageData) ThumbnailImage() (image.Image, error) { photoImage, err := img.PhotoImage() if err != nil {