package main import ( "bytes" "encoding/json" "flag" "fmt" "image/png" "net/http" "os" "path" "strings" "github.com/kettek/apng" ) var cacheDirectory string func handleUpload(w http.ResponseWriter, r *http.Request) { inf, header, err := r.FormFile("image") if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } defer inf.Close() if !strings.HasSuffix(header.Filename, ".pixil") { http.Error(w, "Invalid file type", http.StatusBadRequest) return } var pixil Pixil if err := json.NewDecoder(inf).Decode(&pixil); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } if pixil.Width != 8 || pixil.Height != 8 { http.Error(w, "Invalid image size", http.StatusBadRequest) return } outRaw, err := os.Create(path.Join(cacheDirectory, "wallart.bin")) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } defer outRaw.Close() outPng, err := os.Create(path.Join(cacheDirectory, "wallart.png")) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } defer outPng.Close() // You only get 8 frames max numFrames := len(pixil.Frames) if numFrames > 8 { numFrames = 8 } outImage := apng.APNG{ Frames: make([]apng.Frame, len(pixil.Frames)), } for i := 0; i < numFrames; i++ { frame := pixil.Frames[i] preview := frame.GetPreview() if preview == nil { http.Error(w, "Invalid frame", http.StatusBadRequest) return } img, err := png.Decode(bytes.NewReader(preview)) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } // Dump it to the raw file for y := 0; y < 8; y++ { for x := 0; x < 8; x++ { r, g, b, _ := img.At(x, y).RGBA() outRaw.Write([]byte{ byte(r >> 8), byte(g >> 8), byte(b >> 8), }) } } outImage.Frames[i] = apng.Frame{ Image: img, DelayNumerator: 1, DelayDenominator: 2, } } if err := apng.Encode(outPng, outImage); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } fmt.Fprintln(w, "It worked") } func main() { listen := flag.String("listen", ":8080", "listen address") web := flag.String("web", "web", "web directory") flag.StringVar(&cacheDirectory, "cache", "cache", "cache directory") flag.Parse() cacheDir := http.Dir(cacheDirectory) http.HandleFunc("/upload", handleUpload) http.Handle("/wallart.bin", http.FileServer(cacheDir)) http.Handle("/wallart.png", http.FileServer(cacheDir)) http.Handle("/", http.FileServer(http.Dir(*web))) http.ListenAndServe(*listen, nil) }