package main import ( "flag" "fmt" "image" "image/color" "image/jpeg" "image/png" "net/http" "os" "strconv" "github.com/gin-gonic/gin" "github.com/makeworld-the-better-one/dither/v2" ) func hw(ctx *gin.Context) { ctx.JSON(http.StatusOK, gin.H{"message": 123}) } func heart(ctx *gin.Context) { ctx.JSON(http.StatusOK, gin.H{"emo": "<3"}) } func ditherImageHandler(ctx *gin.Context) { fileHeader, fileErr := ctx.FormFile("source") if fileErr != nil { fmt.Printf("Could not fetch form file; %v", fileErr) ctx.Status(http.StatusBadRequest) return } sourceFile, sourceFileErr := fileHeader.Open() if sourceFileErr != nil { fmt.Printf("Could not open source file; %v", sourceFileErr) ctx.Status(http.StatusBadRequest) return } defer sourceFile.Close() img, formatName, decodeErr := image.Decode(sourceFile) fmt.Printf("Format: %v", formatName) if decodeErr != nil { fmt.Printf("Failed to decode image from stream: %v", decodeErr) ctx.JSON(http.StatusBadRequest, gin.H{"error:": decodeErr.Error()}) return } palette := []color.Color{color.Black, color.White} ditherer := dither.NewDitherer(palette) ditherer.Matrix = dither.FalseFloydSteinberg ditheredImage := ditherer.DitherCopy(img) var encodeErr error switch formatName { case "png": encodeErr = png.Encode(ctx.Writer, ditheredImage) case "jpeg": options := jpeg.Options{Quality: 100} encodeErr = jpeg.Encode(ctx.Writer, ditheredImage, &options) default: fmt.Printf("Failed to encode dithered image: %v", decodeErr) ctx.JSON(http.StatusBadRequest, gin.H{"error:": "format unsupported: " + formatName}) } if encodeErr != nil { fmt.Printf("Failed to encode dithered image: %v", decodeErr) ctx.JSON(http.StatusBadRequest, gin.H{"error:": encodeErr.Error()}) return } if encodeErr != nil { fmt.Printf("Failed to stream image: %v", encodeErr) ctx.JSON(http.StatusBadRequest, gin.H{"error:": encodeErr.Error()}) return } ctx.Header("Content-Type", "image/png") ctx.Status(http.StatusCreated) } func ditherCat(ctx *gin.Context) { picStream, err := os.Open("./.output-temp/cat.png") if err != nil { fmt.Printf("Failed to stream image: %v", err) ctx.JSON(http.StatusBadRequest, gin.H{"error:": err.Error()}) return } defer picStream.Close() img, formatName, decodeErr := image.Decode(picStream) fmt.Printf("Format: %v", formatName) if decodeErr != nil { fmt.Printf("Failed to decode image from stream: %v", decodeErr) ctx.JSON(http.StatusBadRequest, gin.H{"error:": decodeErr.Error()}) return } palette := []color.Color{color.Black, color.White} ditherer := dither.NewDitherer(palette) ditherer.Matrix = dither.FalseFloydSteinberg ditheredImage := ditherer.DitherCopy(img) encodeErr := png.Encode(ctx.Writer, ditheredImage) if encodeErr != nil { fmt.Printf("Failed to encode dithered image: %v", decodeErr) ctx.JSON(http.StatusBadRequest, gin.H{"error:": encodeErr.Error()}) return } ctx.Header("Content-Type", "image/png") } func main() { port := flag.Int("p", 8080, "port to listen on") flag.Parse() router := gin.Default() router.GET("/", hw) router.GET("/heart", heart) router.GET("/cat", ditherCat) router.POST("/dither", ditherImageHandler) //router.POST("dither",ditherImage()) err := router.Run(":" + strconv.Itoa(*port)) if err != nil { msg := fmt.Errorf("failed to run router: %v", err) fmt.Println(msg) } }