我需要一个网络路由,该网络路由使用.jpg
和来自磁盘的多个.png
文件生成映像,并将其返回给客户端。由于此操作会占用大量CPU,因此我决定尝试使用go getComposed()
和简单的img := getComposed()
,但似乎两种方法都可以同时使用。为什么这样?以及如何提高此具体案例的性能?
package main
import (
"bytes"
"fmt"
"github.com/valyala/fasthttp"
"image"
"image/draw"
"image/jpeg"
"image/png"
"log"
"os"
"strconv"
"time"
)
func getImage(path string, ext string) image.Image {
opened, err := os.Open(path)
defer opened.Close()
if err != nil {
log.Fatalf("failed to open: %s", err)
}
switch ext {
default:
fallthrough
case "png":
img, _ := png.Decode(opened)
return img
case "jpg":
img, _ := jpeg.Decode(opened)
return img
}
}
func getComposed() image.Image {
start := time.Now()
bg := getImage("bgImages/bg.1000.jpg", "jpg")
bgBounds := bg.Bounds()
result := image.NewRGBA(bgBounds)
draw.Draw(result, bgBounds, bg, image.ZP, draw.Src)
dir, _ := os.Open("composeImages")
files, _ := dir.Readdir(-1)
for _, file := range files {
composedPng := getImage("composeImages/" + file.Name(), "png")
draw.Draw(result, composedPng.Bounds(), composedPng, image.ZP, draw.Over)
}
elapsed := time.Since(start)
fmt.Println("IMAGE Elapsed %s", elapsed)
return result
}
func handler(ctx *fasthttp.RequestCtx) {
start := time.Now()
//img := getComposed()
// OR
messages := make(chan image.Image)
go func() { messages <- getComposed() }()
img := <-messages
buffer := new(bytes.Buffer)
if err := jpeg.Encode(buffer, img, nil); err != nil {
log.Println("unable to encode image.")
}
ctx.SetContentType("image/jpeg")
ctx.Response.Header.Set("Content-Length", strconv.Itoa(len(buffer.Bytes())))
elapsed := time.Since(start)
fmt.Println("SERVER Elapsed %s", elapsed)
if _, err := ctx.Write(buffer.Bytes()); err != nil {
log.Println("unable to write image.")
}
}
func main() {
fasthttp.ListenAndServe(":8002", handler)
}