Refine the image cache things.

This commit is contained in:
zicla
2018-11-23 12:19:25 +08:00
parent 6c19a3d321
commit ea9c66f7b2
3 changed files with 151 additions and 143 deletions

View File

@ -3,7 +3,6 @@ package rest
import ( import (
"fmt" "fmt"
"net/http" "net/http"
"os"
"regexp" "regexp"
"strconv" "strconv"
"strings" "strings"
@ -441,41 +440,14 @@ func (this *AlienController) Download(writer http.ResponseWriter, request *http.
if imageProcess == "resize" { if imageProcess == "resize" {
//如果是图片,那么能用缓存就用缓存 //如果是图片,那么能用缓存就用缓存
uri := request.RequestURI imageCache := this.imageCacheDao.FindByUri(request.RequestURI)
imageCache := this.imageCacheDao.FindByUri(uri) if imageCache == nil {
if imageCache != nil { imageCache = this.imageCacheService.cacheImage(writer, request, matter)
//直接使用缓存中的信息
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)
} }
//直接使用缓存中的信息
this.matterService.DownloadFile(writer, request, CONFIG.MatterPath+imageCache.Path, matter.Name)
} else { } else {
this.matterService.DownloadFile(writer, request, CONFIG.MatterPath+matter.Path, matter.Name) this.matterService.DownloadFile(writer, request, CONFIG.MatterPath+matter.Path, matter.Name)
} }

View File

@ -1,9 +1,19 @@
package rest package rest
import (
"net/http"
"image"
"os"
"strconv"
"github.com/disintegration/imaging"
"net/url"
)
//@Service //@Service
type ImageCacheService struct { type ImageCacheService struct {
Bean Bean
imageCacheDao *ImageCacheDao imageCacheDao *ImageCacheDao
userDao *UserDao
} }
//初始化方法 //初始化方法
@ -15,6 +25,11 @@ func (this *ImageCacheService) Init(context *Context) {
this.imageCacheDao = b 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 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
}

View File

@ -3,8 +3,6 @@ package rest
import ( import (
"errors" "errors"
"fmt" "fmt"
"github.com/disintegration/imaging"
"image"
"io" "io"
"mime" "mime"
"mime/multipart" "mime/multipart"
@ -248,113 +246,6 @@ func (this *MatterService) Crawl(url string, filename string, user *User, puuid
return matter 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. // httpRange specifies the byte range to be sent to the client.
type httpRange struct { type httpRange struct {
start, length int64 start, length int64