Parcourir la source

Added RAW preview feature in the share interface (#226)

* Support RAW image formats (DNG, CR2, ARW, NEF, RAF, ORF) in share interface

When a shared RAW file is previewed, the server now converts it to JPEG on
the fly using the existing metadata.RenderRAWImage() pipeline, so browsers
can display it. RAW files are also routed to the image.html preview template
instead of the generic default.html template.

https://claude.ai/code/session_01ENWo7sGbH6sCw64qiU1jwp

* Fix RAW download being served as JPEG instead of original file

The download mode check was happening after the RAW→JPEG conversion, so
/media/download/?file=...dng was sending a JPEG instead of the original DNG.
Move the RAW rendering block to after the download mode detection so that
download requests always get the original file.

https://claude.ai/code/session_01ENWo7sGbH6sCw64qiU1jwp

---------

Co-authored-by: Claude <noreply@anthropic.com>
Alan Yeung il y a 2 semaines
Parent
commit
9e3d31e265
2 fichiers modifiés avec 28 ajouts et 17 suppressions
  1. 14 14
      src/mod/media/mediaserver/mediaserver.go
  2. 14 3
      src/mod/share/share.go

+ 14 - 14
src/mod/media/mediaserver/mediaserver.go

@@ -180,8 +180,20 @@ func (s *Instance) ServerMedia(w http.ResponseWriter, r *http.Request) {
 
 	targetFshAbs := targetFsh.FileSystemAbstraction
 
-	// Check if this is a RAW image file and render it as JPEG
-	if metadata.IsRawImageFile(realFilepath) {
+	//Check if downloadMode
+	downloadMode := false
+	dw, _ := utils.GetPara(r, "download")
+	if dw == "true" {
+		downloadMode = true
+	}
+
+	//New download implementations, allow /download to be used instead of &download=true
+	if strings.Contains(r.RequestURI, "media/download/?file=") {
+		downloadMode = true
+	}
+
+	// Check if this is a RAW image file and render it as JPEG (preview only, not download)
+	if !downloadMode && metadata.IsRawImageFile(realFilepath) {
 		jpegData, err := metadata.RenderRAWImage(targetFsh, realFilepath)
 		if err != nil {
 			// If RAW rendering fails, fall back to serving the raw file
@@ -195,18 +207,6 @@ func (s *Instance) ServerMedia(w http.ResponseWriter, r *http.Request) {
 		}
 	}
 
-	//Check if downloadMode
-	downloadMode := false
-	dw, _ := utils.GetPara(r, "download")
-	if dw == "true" {
-		downloadMode = true
-	}
-
-	//New download implementations, allow /download to be used instead of &download=true
-	if strings.Contains(r.RequestURI, "media/download/?file=") {
-		downloadMode = true
-	}
-
 	//Serve the file
 	if downloadMode {
 		escapedRealFilepath, err := url.PathUnescape(realFilepath)

+ 14 - 3
src/mod/share/share.go

@@ -769,8 +769,18 @@ func (s *Manager) HandleShareAccess(w http.ResponseWriter, r *http.Request) {
 			} else if directServe {
 				w.Header().Set("Access-Control-Allow-Origin", "*")
 				w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
-				w.Header().Set("Content-Type", contentType)
-				if targetFsh.RequireBuffer {
+				if metadata.IsRawImageFile(fileRuntimeAbsPath) {
+					// Convert RAW image to JPEG for browser display
+					jpegData, err := metadata.RenderRAWImage(targetFsh, fileRuntimeAbsPath)
+					if err != nil {
+						w.WriteHeader(http.StatusInternalServerError)
+						w.Write([]byte("500 - Failed to render RAW image: " + err.Error()))
+						return
+					}
+					w.Header().Set("Content-Type", "image/jpeg")
+					w.Write(jpegData)
+				} else if targetFsh.RequireBuffer {
+					w.Header().Set("Content-Type", contentType)
 					f, err := targetFshAbs.ReadStream(fileRuntimeAbsPath)
 					if err != nil {
 						w.WriteHeader(http.StatusInternalServerError)
@@ -780,6 +790,7 @@ func (s *Manager) HandleShareAccess(w http.ResponseWriter, r *http.Request) {
 					defer f.Close()
 					io.Copy(w, f)
 				} else {
+					w.Header().Set("Content-Type", contentType)
 					f, err := targetFshAbs.Open(fileRuntimeAbsPath)
 					if err != nil {
 						w.WriteHeader(http.StatusInternalServerError)
@@ -811,7 +822,7 @@ func (s *Manager) HandleShareAccess(w http.ResponseWriter, r *http.Request) {
 					previewTemplate = filepath.Join(templateRoot, "video.html")
 				} else if ext == ".mp3" || ext == ".wav" || ext == ".flac" || ext == ".ogg" {
 					previewTemplate = filepath.Join(templateRoot, "audio.html")
-				} else if ext == ".png" || ext == ".jpg" || ext == ".jpeg" || ext == ".webp" {
+				} else if ext == ".png" || ext == ".jpg" || ext == ".jpeg" || ext == ".webp" || metadata.IsRawImageFile(fileRuntimeAbsPath) {
 					previewTemplate = filepath.Join(templateRoot, "image.html")
 				} else if ext == ".pdf" {
 					previewTemplate = filepath.Join(templateRoot, "iframe.html")