diff --git a/main.go b/main.go index 14922a6..15544c6 100644 --- a/main.go +++ b/main.go @@ -2,10 +2,15 @@ package main import ( "encoding/gob" + "errors" "log" + "os" + "path" "strconv" "strings" + "git.trj.tw/golang/mtfosbot/module/utils" + "git.trj.tw/golang/mtfosbot/model" "git.trj.tw/golang/mtfosbot/module/background" "git.trj.tw/golang/mtfosbot/module/config" @@ -38,6 +43,18 @@ func main() { go twitchirc.InitIRC() + // create thumbnail directory + conf := config.GetConf() + if !utils.CheckExists(conf.ImageRoot, true) { + log.Fatal(errors.New("image root not exists")) + } + if !utils.CheckExists(path.Join(conf.ImageRoot, "thumbnail"), true) { + err = os.MkdirAll(path.Join(conf.ImageRoot, "thumbnail"), 0775) + if err != nil { + log.Fatal(err) + } + } + server.Run(strings.Join([]string{":", strconv.Itoa(config.GetConf().Port)}, "")) } diff --git a/router/rimg/rimg.go b/router/rimg/rimg.go index 61ae1d3..cf4437d 100644 --- a/router/rimg/rimg.go +++ b/router/rimg/rimg.go @@ -7,7 +7,7 @@ import ( "image/jpeg" _ "image/jpeg" _ "image/png" - "io/ioutil" + "io" "os" "path" "strconv" @@ -19,8 +19,23 @@ import ( "git.trj.tw/golang/mtfosbot/module/utils" ) +func resizeImage(fio io.Reader, size int, wgth bool) (img image.Image, err error) { + img, _, err = image.Decode(fio) + w := 0 + h := 0 + if wgth { + w = size + } else { + h = size + } + + img = resize.Resize(uint(w), uint(h), img, resize.Lanczos3) + return +} + // GetOriginImage - func GetOriginImage(c *context.Context) { + // max 1024 fname := c.Param("imgname") conf := config.GetConf() imgP := utils.ParsePath(conf.ImageRoot) @@ -44,28 +59,25 @@ func GetOriginImage(c *context.Context) { } defer fileBuf.Close() - imgf, _, err := image.DecodeConfig(fileBuf) + imgf, format, err := image.DecodeConfig(fileBuf) + if err != nil { + c.ServerError(nil) + return + } + + // reset pointer to 0 + _, err = fileBuf.Seek(0, 0) if err != nil { c.ServerError(nil) return } if imgf.Height > 1024 || imgf.Width > 1024 { - img, _, err := image.Decode(fileBuf) - if err != nil { - c.ServerError(nil) - return - } - w := 0 - h := 0 - if imgf.Width > imgf.Height { - w = 1024 - } else { - h = 1024 - } + img, err := resizeImage(fileBuf, 1024, imgf.Width > imgf.Height) + buf := new(bytes.Buffer) - m := resize.Resize(uint(w), uint(h), img, resize.Bilinear) - err = jpeg.Encode(buf, m, nil) + + err = jpeg.Encode(buf, img, nil) if err != nil { c.ServerError(nil) return @@ -79,12 +91,167 @@ func GetOriginImage(c *context.Context) { return } - buf, err := ioutil.ReadAll(fileBuf) + // check type + if format != "jpeg" { + img, _, err := image.Decode(fileBuf) + if err != nil { + c.ServerError(nil) + return + } + buf := new(bytes.Buffer) + err = jpeg.Encode(buf, img, nil) + if err != nil { + c.ServerError(nil) + return + } + + c.Writer.Header().Set("Content-Type", "image/jpeg") + io.Copy(c.Writer, buf) + return + } + c.Writer.Header().Set("Content-Type", "image/jpeg") - c.Writer.Header().Set("Content-Length", strconv.Itoa(len(buf))) - _, err = c.Writer.Write(buf) + io.Copy(c.Writer, fileBuf) +} + +// GetThumbnailImage - +func GetThumbnailImage(c *context.Context) { + // max 240 + fname := c.Param("imgname") + conf := config.GetConf() + imgP := utils.ParsePath(conf.ImageRoot) + exists := utils.CheckExists(imgP, true) + if !exists { + c.NotFound("image path not found") + return + } + + thumbP := path.Join(imgP, "thumbnail", fname) + genNew := false + if !utils.CheckExists(thumbP, false) { + genNew = true + thumbP = path.Join(imgP, fname) + exists = utils.CheckExists(thumbP, false) + if !exists { + c.NotFound("image file not found") + return + } + } + + filebuf, err := os.Open(thumbP) if err != nil { c.ServerError(nil) return } + defer filebuf.Close() + + imgconf, format, err := image.DecodeConfig(filebuf) + if err != nil { + c.ServerError(nil) + return + } + + // reset file reader ptr + _, err = filebuf.Seek(0, 0) + if err != nil { + c.ServerError(nil) + return + } + + if imgconf.Height > 240 || imgconf.Width > 240 { + img, err := resizeImage(filebuf, 240, imgconf.Width > imgconf.Height) + if err != nil { + c.ServerError(nil) + return + } + + buf := new(bytes.Buffer) + err = jpeg.Encode(buf, img, nil) + if err != nil { + c.ServerError(nil) + return + } + breader := bytes.NewReader(buf.Bytes()) + + if genNew { + savep := path.Join(conf.ImageRoot, "thumbnail", fname) + err := saveNewThumbnail(breader, savep) + if err != nil { + c.ServerError(nil) + return + } + _, err = breader.Seek(0, 0) + if err != nil { + c.ServerError(nil) + return + } + } + + c.Writer.Header().Set("Content-Type", "image/jpeg") + io.Copy(c.Writer, breader) + return + } + + if format != "jpeg" { + img, _, err := image.Decode(filebuf) + if err != nil { + c.ServerError(nil) + return + } + buf := new(bytes.Buffer) + err = jpeg.Encode(buf, img, nil) + if err != nil { + c.ServerError(nil) + return + } + + breader := bytes.NewReader(buf.Bytes()) + + savep := path.Join(conf.ImageRoot, "thumbnail", fname) + err = saveNewThumbnail(breader, savep) + if err != nil { + c.ServerError(nil) + return + } + + _, err = breader.Seek(0, 0) + if err != nil { + c.ServerError(nil) + return + } + + c.Writer.Header().Set("Content-Type", "image/jpeg") + io.Copy(c.Writer, breader) + return + } + + if genNew { + savep := path.Join(conf.ImageRoot, "thumbnail", fname) + err := saveNewThumbnail(filebuf, savep) + if err != nil { + c.ServerError(nil) + return + } + _, err = filebuf.Seek(0, 0) + if err != nil { + c.ServerError(nil) + return + } + } + + c.Writer.Header().Set("Content-Type", "image/jpeg") + io.Copy(c.Writer, filebuf) +} + +func saveNewThumbnail(fio io.Reader, newp string) (err error) { + out, err := os.Create(newp) + if err != nil { + return err + } + _, err = io.Copy(out, fio) + if err != nil { + return err + } + + return } diff --git a/router/routes/routes.go b/router/routes/routes.go index 47fe886..d8b5058 100644 --- a/router/routes/routes.go +++ b/router/routes/routes.go @@ -51,10 +51,8 @@ func SetRoutes(r *gin.Engine) { imageProcGroup := r.Group("/image") { - imageProcGroup.GET("/origin", func(c *gin.Context) { - c.String(200, "test msg") - }) imageProcGroup.GET("/origin/:imgname", context.PatchCtx(rimg.GetOriginImage)) + imageProcGroup.GET("/thumbnail/:imgname", context.PatchCtx(rimg.GetThumbnailImage)) } apiGroup := r.Group("/api")