Refine the image cache things.
This commit is contained in:
@ -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)
|
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
this.matterService.DownloadFile(writer, request, CONFIG.MatterPath+matter.Path, matter.Name)
|
this.matterService.DownloadFile(writer, request, CONFIG.MatterPath+matter.Path, matter.Name)
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
}
|
||||||
|
@ -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
|
||||||
|
Reference in New Issue
Block a user