173 lines
4.6 KiB
Go
173 lines
4.6 KiB
Go
package rest
|
||
|
||
import (
|
||
"net/http"
|
||
"image"
|
||
"os"
|
||
"strconv"
|
||
"github.com/disintegration/imaging"
|
||
"net/url"
|
||
)
|
||
|
||
//@Service
|
||
type ImageCacheService struct {
|
||
Bean
|
||
imageCacheDao *ImageCacheDao
|
||
userDao *UserDao
|
||
}
|
||
|
||
//初始化方法
|
||
func (this *ImageCacheService) Init(context *Context) {
|
||
|
||
//手动装填本实例的Bean. 这里必须要用中间变量方可。
|
||
b := context.GetBean(this.imageCacheDao)
|
||
if b, ok := b.(*ImageCacheDao); ok {
|
||
this.imageCacheDao = b
|
||
}
|
||
|
||
b = context.GetBean(this.userDao)
|
||
if b, ok := b.(*UserDao); ok {
|
||
this.userDao = b
|
||
}
|
||
|
||
}
|
||
|
||
//获取某个文件的详情,会把父级依次倒着装进去。如果中途出错,直接抛出异常。
|
||
func (this *ImageCacheService) Detail(uuid string) *ImageCache {
|
||
|
||
imageCache := this.imageCacheDao.CheckByUuid(uuid)
|
||
|
||
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
|
||
}
|