package main import ( "crypto/md5" "fmt" "golang.org/x/image/webp" "image/jpeg" "io" "log" "net/http" "os" "strings" "time" ) func main() { _, err := os.Stat("cache") if err == nil { err := os.RemoveAll("cache") if err != nil { log.Fatal(err) } } err = os.Mkdir("cache", os.ModeDir|os.ModePerm) if err != nil { log.Fatal(err) } http.HandleFunc("/", webp2jpgHandler) err = http.ListenAndServe(":9999", nil) if err != nil { log.Fatal(err) } } func hitCache(md5Path string, writer http.ResponseWriter) bool { startTime := time.Now().UnixNano() _, err := os.Stat("cache/" + md5Path) if err != nil { return false } file, err := os.OpenFile("cache/"+md5Path, os.O_RDONLY, os.FileMode(0644)) defer file.Close() if err != nil { log.Fatal(err) } header := writer.Header() header.Set("Access-Control-Allow-Origin", "*") header.Set("content-type", "image/jpeg") if _, err := io.Copy(writer, file); err != nil { log.Fatal(err) } endTime := time.Now().UnixNano() fmt.Printf("命中缓存:%dμs\n", (endTime-startTime)/1e3) return true } func webp2jpg(path string, md5Path string, writer http.ResponseWriter) { startTime := time.Now().UnixNano() resp, getErr := http.Get(path) if getErr != nil { log.Print(getErr) writer.WriteHeader(404) return } endTime := time.Now().UnixNano() fmt.Printf("下载耗时:%dms\n", (endTime-startTime)/1e6) startTime = time.Now().UnixNano() m, err := webp.Decode(resp.Body) if err != nil { log.Fatal(err) } endTime = time.Now().UnixNano() fmt.Printf("解码耗时:%dms\n", (endTime-startTime)/1e6) header := writer.Header() header.Set("Access-Control-Allow-Origin", "*") header.Set("content-type", "image/jpeg") file, err := os.OpenFile("cache/"+md5Path, os.O_CREATE|os.O_WRONLY, os.FileMode(0644)) defer file.Close() if err != nil { log.Fatal(err) } startTime = time.Now().UnixNano() err = jpeg.Encode(io.MultiWriter(writer, file), m, &jpeg.Options{Quality: 50}) if err != nil { log.Fatal(err) } endTime = time.Now().UnixNano() fmt.Printf("编码耗时:%dms\n", (endTime-startTime)/1e6) } func webp2jpgHandler(writer http.ResponseWriter, request *http.Request) { if !(strings.HasPrefix(request.URL.RawQuery, "http") && strings.HasSuffix(request.URL.RawQuery, ".webp")) { writer.WriteHeader(404) return } m := md5.Sum([]byte(request.URL.RawQuery)) md5Path := fmt.Sprintf("%x", m) if hitCache(md5Path, writer) { return } webp2jpg(request.URL.RawQuery, md5Path, writer) }