154 lines
3.3 KiB
Go
154 lines
3.3 KiB
Go
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)
|
|
}
|
|
}
|