From ea9c66f7b2384187f4bc048f86bde10b34277356 Mon Sep 17 00:00:00 2001 From: zicla Date: Fri, 23 Nov 2018 12:19:25 +0800 Subject: [PATCH] Refine the image cache things. --- rest/alien_controller.go | 40 ++-------- rest/image_cache_service.go | 145 ++++++++++++++++++++++++++++++++++++ rest/matter_service.go | 109 --------------------------- 3 files changed, 151 insertions(+), 143 deletions(-) diff --git a/rest/alien_controller.go b/rest/alien_controller.go index 5d6bbdd..d9c313d 100644 --- a/rest/alien_controller.go +++ b/rest/alien_controller.go @@ -3,7 +3,6 @@ package rest import ( "fmt" "net/http" - "os" "regexp" "strconv" "strings" @@ -441,41 +440,14 @@ func (this *AlienController) Download(writer http.ResponseWriter, request *http. if imageProcess == "resize" { //如果是图片,那么能用缓存就用缓存 - uri := request.RequestURI - imageCache := this.imageCacheDao.FindByUri(uri) - if imageCache != nil { - - //直接使用缓存中的信息 - this.matterService.DownloadFile(writer, request, CONFIG.MatterPath+imageCache.Path, matter.Name) - - } else { - - //resize图片 - dstImage := this.matterService.ResizeImage(request, CONFIG.MatterPath+matter.Path) - - user := this.userDao.FindByUuid(matter.UserUuid) - //获取文件应该存放在的物理路径的绝对路径和相对路径。 - absolutePath, relativePath := GetUserFilePath(user.Username, true) - absolutePath = absolutePath + "/" + filename - relativePath = relativePath + "/" + filename - - fileWriter, err := os.Create(absolutePath) - this.PanicError(err) - defer fileWriter.Close() - - //生成的图片输出到两个writer中去 - this.matterService.DownloadImage(writer, fileWriter, dstImage, matter.Name) - - //相关信息写到缓存中去 - imageCache = &ImageCache{ - UserUuid: matter.UserUuid, - MatterUuid: matter.Uuid, - Uri: uri, - Path: relativePath, - } - this.imageCacheDao.Create(imageCache) + imageCache := this.imageCacheDao.FindByUri(request.RequestURI) + if imageCache == nil { + imageCache = this.imageCacheService.cacheImage(writer, request, matter) } + //直接使用缓存中的信息 + this.matterService.DownloadFile(writer, request, CONFIG.MatterPath+imageCache.Path, matter.Name) + } else { this.matterService.DownloadFile(writer, request, CONFIG.MatterPath+matter.Path, matter.Name) } diff --git a/rest/image_cache_service.go b/rest/image_cache_service.go index e1cbb10..4a1851c 100644 --- a/rest/image_cache_service.go +++ b/rest/image_cache_service.go @@ -1,9 +1,19 @@ package rest +import ( + "net/http" + "image" + "os" + "strconv" + "github.com/disintegration/imaging" + "net/url" +) + //@Service type ImageCacheService struct { Bean imageCacheDao *ImageCacheDao + userDao *UserDao } //初始化方法 @@ -15,6 +25,11 @@ func (this *ImageCacheService) Init(context *Context) { this.imageCacheDao = b } + b = context.GetBean(this.userDao) + if b, ok := b.(*UserDao); ok { + this.userDao = b + } + } //获取某个文件的详情,会把父级依次倒着装进去。如果中途出错,直接抛出异常。 @@ -25,3 +40,133 @@ func (this *ImageCacheService) Detail(uuid string) *ImageCache { return imageCache } +//图片预处理功能。 +func (this *ImageCacheService) ResizeImage(request *http.Request, filePath string) *image.NRGBA { + + diskFile, err := os.Open(filePath) + this.PanicError(err) + defer diskFile.Close() + + imageResizeM := request.FormValue("imageResizeM") + if imageResizeM == "" { + imageResizeM = "fit" + } else if imageResizeM != "fit" && imageResizeM != "fill" && imageResizeM != "fixed" { + panic("imageResizeM参数错误") + } + imageResizeWStr := request.FormValue("imageResizeW") + var imageResizeW int + if imageResizeWStr != "" { + imageResizeW, err = strconv.Atoi(imageResizeWStr) + this.PanicError(err) + if imageResizeW < 1 || imageResizeW > 4096 { + panic("缩放尺寸不能超过4096") + } + } + imageResizeHStr := request.FormValue("imageResizeH") + var imageResizeH int + if imageResizeHStr != "" { + imageResizeH, err = strconv.Atoi(imageResizeHStr) + this.PanicError(err) + if imageResizeH < 1 || imageResizeH > 4096 { + panic("缩放尺寸不能超过4096") + } + } + + //单边缩略 + if imageResizeM == "fit" { + //将图缩略成宽度为100,高度按比例处理。 + if imageResizeW > 0 { + src, err := imaging.Decode(diskFile) + this.PanicError(err) + return imaging.Resize(src, imageResizeW, 0, imaging.Lanczos) + + } else if imageResizeH > 0 { + //将图缩略成高度为100,宽度按比例处理。 + src, err := imaging.Decode(diskFile) + this.PanicError(err) + return imaging.Resize(src, 0, imageResizeH, imaging.Lanczos) + + } else { + panic("单边缩略必须指定imageResizeW或imageResizeH") + } + } else if imageResizeM == "fill" { + //固定宽高,自动裁剪 + if imageResizeW > 0 && imageResizeH > 0 { + src, err := imaging.Decode(diskFile) + this.PanicError(err) + return imaging.Fill(src, imageResizeW, imageResizeH, imaging.Center, imaging.Lanczos) + + } else { + panic("固定宽高,自动裁剪 必须同时指定imageResizeW和imageResizeH") + } + } else if imageResizeM == "fixed" { + //强制宽高缩略 + if imageResizeW > 0 && imageResizeH > 0 { + src, err := imaging.Decode(diskFile) + this.PanicError(err) + return imaging.Resize(src, imageResizeW, imageResizeH, imaging.Lanczos) + + } else { + panic("强制宽高缩略必须同时指定imageResizeW和imageResizeH") + } + } else { + panic("不支持" + imageResizeM + "处理模式") + } +} + +//缓存一张处理完毕了的图片 +func (this *ImageCacheService) cacheImage(writer http.ResponseWriter, request *http.Request, matter *Matter) *ImageCache { + + // 防止中文乱码 + fileName := url.QueryEscape(matter.Name) + + //当前的文件是否是图片,只有图片才能处理。 + extension := GetExtension(fileName) + formats := map[string]imaging.Format{ + ".jpg": imaging.JPEG, + ".jpeg": imaging.JPEG, + ".png": imaging.PNG, + ".tif": imaging.TIFF, + ".tiff": imaging.TIFF, + ".bmp": imaging.BMP, + ".gif": imaging.GIF, + } + + format, ok := formats[extension] + if !ok { + panic("该图片格式不支持处理") + } + + //resize图片 + dstImage := this.ResizeImage(request, CONFIG.MatterPath+matter.Path) + + user := this.userDao.FindByUuid(matter.UserUuid) + //获取文件应该存放在的物理路径的绝对路径和相对路径。 + absolutePath, relativePath := GetUserFilePath(user.Username, true) + absolutePath = absolutePath + "/" + fileName + relativePath = relativePath + "/" + fileName + + fileWriter, err := os.Create(absolutePath) + this.PanicError(err) + defer fileWriter.Close() + + //处理后的图片存放在本地 + err = imaging.Encode(fileWriter, dstImage, format) + this.PanicError(err) + + //获取新文件的大小 + fileInfo, err := fileWriter.Stat() + this.PanicError(err) + + //相关信息写到缓存中去 + imageCache := &ImageCache{ + UserUuid: matter.UserUuid, + MatterUuid: matter.Uuid, + Uri: request.RequestURI, + Size: fileInfo.Size(), + Path: relativePath, + } + this.imageCacheDao.Create(imageCache) + + return imageCache +} diff --git a/rest/matter_service.go b/rest/matter_service.go index 99aaaa4..1f9c156 100644 --- a/rest/matter_service.go +++ b/rest/matter_service.go @@ -3,8 +3,6 @@ package rest import ( "errors" "fmt" - "github.com/disintegration/imaging" - "image" "io" "mime" "mime/multipart" @@ -248,113 +246,6 @@ func (this *MatterService) Crawl(url string, filename string, user *User, puuid return matter } -//图片预处理功能。 -func (this *MatterService) ResizeImage(request *http.Request, filePath string) *image.NRGBA { - - diskFile, err := os.Open(filePath) - this.PanicError(err) - defer diskFile.Close() - - imageResizeM := request.FormValue("imageResizeM") - if imageResizeM == "" { - imageResizeM = "fit" - } else if imageResizeM != "fit" && imageResizeM != "fill" && imageResizeM != "fixed" { - panic("imageResizeM参数错误") - } - imageResizeWStr := request.FormValue("imageResizeW") - var imageResizeW int - if imageResizeWStr != "" { - imageResizeW, err = strconv.Atoi(imageResizeWStr) - this.PanicError(err) - if imageResizeW < 1 || imageResizeW > 4096 { - panic("缩放尺寸不能超过4096") - } - } - imageResizeHStr := request.FormValue("imageResizeH") - var imageResizeH int - if imageResizeHStr != "" { - imageResizeH, err = strconv.Atoi(imageResizeHStr) - this.PanicError(err) - if imageResizeH < 1 || imageResizeH > 4096 { - panic("缩放尺寸不能超过4096") - } - } - - //单边缩略 - if imageResizeM == "fit" { - //将图缩略成宽度为100,高度按比例处理。 - if imageResizeW > 0 { - src, err := imaging.Decode(diskFile) - this.PanicError(err) - return imaging.Resize(src, imageResizeW, 0, imaging.Lanczos) - - } else if imageResizeH > 0 { - //将图缩略成高度为100,宽度按比例处理。 - src, err := imaging.Decode(diskFile) - this.PanicError(err) - return imaging.Resize(src, 0, imageResizeH, imaging.Lanczos) - - } else { - panic("单边缩略必须指定imageResizeW或imageResizeH") - } - } else if imageResizeM == "fill" { - //固定宽高,自动裁剪 - if imageResizeW > 0 && imageResizeH > 0 { - src, err := imaging.Decode(diskFile) - this.PanicError(err) - return imaging.Fill(src, imageResizeW, imageResizeH, imaging.Center, imaging.Lanczos) - - } else { - panic("固定宽高,自动裁剪 必须同时指定imageResizeW和imageResizeH") - } - } else if imageResizeM == "fixed" { - //强制宽高缩略 - if imageResizeW > 0 && imageResizeH > 0 { - src, err := imaging.Decode(diskFile) - this.PanicError(err) - return imaging.Resize(src, imageResizeW, imageResizeH, imaging.Lanczos) - - } else { - panic("强制宽高缩略必须同时指定imageResizeW和imageResizeH") - } - } else { - panic("不支持" + imageResizeM + "处理模式") - } -} - -//下载处理后的图片 -func (this *MatterService) DownloadImage(writer http.ResponseWriter, fileWriter io.Writer, dstImage *image.NRGBA, filename string) { - - // 防止中文乱码 - fileName := url.QueryEscape(filename) - mimeType := GetMimeType(fileName) - writer.Header().Set("Content-Type", mimeType) - - //当前的文件是否是图片,只有图片才能处理。 - extension := GetExtension(filename) - formats := map[string]imaging.Format{ - ".jpg": imaging.JPEG, - ".jpeg": imaging.JPEG, - ".png": imaging.PNG, - ".tif": imaging.TIFF, - ".tiff": imaging.TIFF, - ".bmp": imaging.BMP, - ".gif": imaging.GIF, - } - - format, ok := formats[extension] - if !ok { - panic("该图片格式不支持处理") - } - - err := imaging.Encode(writer, dstImage, format) - this.PanicError(err) - - //处理后的图片存放在本地 - err = imaging.Encode(fileWriter, dstImage, format) - this.PanicError(err) -} - // httpRange specifies the byte range to be sent to the client. type httpRange struct { start, length int64