diff --git a/display/pkg/image.go b/display/pkg/image.go new file mode 100644 index 0000000..bd685ad --- /dev/null +++ b/display/pkg/image.go @@ -0,0 +1,19 @@ +package pkg + +import "image" + +func ResizeImage(img image.Image, newWidth, newHeight int) image.Image { + srcBounds := img.Bounds() + srcWidth := srcBounds.Dx() + srcHeight := srcBounds.Dy() + dst := image.NewRGBA(image.Rect(0, 0, newWidth, newHeight)) + for y := range newHeight { + for x := range newWidth { + srcX := x * srcWidth / newWidth + srcY := y * srcHeight / newHeight + c := img.At(srcBounds.Min.X+srcX, srcBounds.Min.Y+srcY) + dst.Set(x, y, c) + } + } + return dst +} diff --git a/display/requests/filePreview.bru b/display/requests/filePreview.bru new file mode 100644 index 0000000..c48c30a --- /dev/null +++ b/display/requests/filePreview.bru @@ -0,0 +1,16 @@ +meta { + name: filePreview + type: http + seq: 9 +} + +get { + url: 127.0.0.1:1323/api/file/preview/titel.jpg + body: none + auth: inherit +} + +settings { + encodeUrl: true + timeout: 0 +} diff --git a/display/web/main.go b/display/web/main.go index 3b260c5..5c1ee55 100644 --- a/display/web/main.go +++ b/display/web/main.go @@ -4,6 +4,9 @@ import ( "bytes" "context" "fmt" + "image" + "image/jpeg" + "image/png" "io" "log/slog" "net/http" @@ -54,6 +57,7 @@ func StartWebServer(v string) { fileGroup.POST("/:path", uploadFileRoute) fileGroup.GET("/:path", downloadFileRoute) fileGroup.PATCH("/:path", openFileRoute) + fileGroup.GET("/preview/:path", previewRoute) err := e.Start(":1323") if err != nil { @@ -316,6 +320,44 @@ func takeScreenshotRoute(ctx echo.Context) error { return nil } +func previewRoute(ctx echo.Context) error { + fullPath := ctx.Get("fullPath").(string) + exists := ctx.Get("fileExists").(bool) + if !exists { + return ctx.JSON(http.StatusNotFound, ErrorResponse{Error: "File not found"}) + } + + f, err := os.Open(fullPath) + if err != nil { + slog.Error("Failed to open file", "file", fullPath, "error", err) + return ctx.JSON(http.StatusInternalServerError, ErrorResponse{Error: "Failed to open file"}) + } + defer f.Close() + + ext := strings.ToLower(filepath.Ext(fullPath)) + var imgData image.Image + switch ext { + case ".jpg", ".jpeg": + imgData, err = jpeg.Decode(f) + case ".png": + imgData, err = png.Decode(f) + default: + return ctx.JSON(http.StatusBadRequest, ErrorResponse{Error: "Unsupported image format for preview"}) + } + if err != nil { + slog.Error("Failed to decode image", "error", err) + return ctx.JSON(http.StatusInternalServerError, ErrorResponse{Error: "Failed to decode image"}) + } + + resized := pkg.ResizeImage(imgData, 100, 100) + var buf bytes.Buffer + if err := png.Encode(&buf, resized); err != nil { + slog.Error("Failed to encode image", "error", err) + return ctx.JSON(http.StatusInternalServerError, ErrorResponse{Error: "Failed to encode image"}) + } + return ctx.Blob(http.StatusOK, "image/png", buf.Bytes()) +} + // Reset previous file views so they dont collide with the new one func resetView() error { err := pkg.KeyboardInput(keybd_event.VK_ESC)