Skip to content

Commit

Permalink
feat: 上传图片自动增加缩略图
Browse files Browse the repository at this point in the history
  • Loading branch information
dingdangdog committed Jun 29, 2024
1 parent a83bc84 commit b5519c6
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 14 deletions.
1 change: 1 addition & 0 deletions server/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ require (
github.com/bytedance/sonic/loader v0.1.1 // indirect
github.com/cloudwego/base64x v0.1.4 // indirect
github.com/cloudwego/iasm v0.2.0 // indirect
github.com/disintegration/imaging v1.6.2
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-playground/locales v0.14.1 // indirect
Expand Down
4 changes: 4 additions & 0 deletions server/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQ
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c=
github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
Expand Down Expand Up @@ -68,6 +70,7 @@ golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc=
golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.16.0 h1:9kloLAKhUufZhA12l5fwnx2NZW39/we1UhBesW433jw=
golang.org/x/image v0.16.0/go.mod h1:ugSZItdV4nOxyqp56HmXwH0Ry0nBCpjnZdpDaIHdoPs=
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
Expand All @@ -76,6 +79,7 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
Expand Down
61 changes: 55 additions & 6 deletions server/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,18 @@ func UploadHandler(c *gin.Context) {
}
url := fileUrl.String()
fileInfo.FileUrl = url
resultDTO.Url = url

// Generate thumbnail
err = generateThumbnail(fileInfo.FilePath, fileInfo.FileName)
thumbFileUrl := strings.Replace(url, config.UserMap[key]+"/", config.UserMap[key]+"/thumb/", 1)

fileInfo.ThumFileUrl = thumbFileUrl
resultDTO.ThumFileUrl = thumbFileUrl
if err != nil {
c.JSON(http.StatusInternalServerError, Result{Code: 500, Message: "Failed to generate thumbnail!" + err.Error()})
return
}

if uploadDTO.WaterMark != "" {
if !contains(config.AllowMarkType, fileType) {
Expand All @@ -90,12 +102,11 @@ func UploadHandler(c *gin.Context) {
backupFileUrl.WriteString(".")
backupFileUrl.WriteString(fileType)
backupUrl := backupFileUrl.String()

fileInfo.BackupFileUrl = backupUrl
resultDTO.BackupUrl = backupUrl
}

resultDTO.Code = 200
resultDTO.Url = url
c.JSON(http.StatusOK, resultDTO)
}

Expand All @@ -120,15 +131,15 @@ func GetImageListHandler(c *gin.Context) {
storeDTO := StoreDTO{}

if value, ok := config.UserMap[key]; ok {
fileList := getFileList(key)
fileList := getFileList(config.UserMap[key] + "/thumb/")
sort.Sort(sort.Reverse(sort.StringSlice(fileList)))

var nList []string
for _, name := range fileList {
if find != "" && !strings.Contains(name, find) {
continue
}
nList = append(nList, config.BaseImageUrl+value+"/"+name)
nList = append(nList, config.BaseImageUrl+value+"/thumb/"+name)
}

storeDTO.Code = 200
Expand All @@ -141,8 +152,8 @@ func GetImageListHandler(c *gin.Context) {
c.JSON(http.StatusOK, storeDTO)
}

func getFileList(key string) []string {
folderPath := filepath.Join(config.ImagePath, config.UserMap[key])
func getFileList(dir string) []string {
folderPath := filepath.Join(config.ImagePath, dir)
var imageList []string

files, err := os.ReadDir(folderPath)
Expand Down Expand Up @@ -213,3 +224,41 @@ func ExportHandler(c *gin.Context) {

http.ServeContent(c.Writer, c.Request, "", fileInfo.ModTime(), file)
}

func GenerateThumb(c *gin.Context) {
key := c.Query("key")
if _, ok := config.UserMap[key]; !ok {
c.JSON(http.StatusForbidden, gin.H{"message": "No Permission!"})
return
}

fileList := getFileList(config.UserMap[key])
thumbList := getFileList(config.UserMap[key] + "/thumb/")

needList := checkFilesNotInThumbList(fileList, thumbList)

for _, fileName := range needList {
generateThumbnail(filepath.Join(config.ImagePath, config.UserMap[key]), fileName)
}
resultDTO := Result{Code: 200, Message: strconv.Itoa(len(needList))}
c.JSON(http.StatusOK, resultDTO) // needList)
}

// checkFilesNotInThumbList 检查 fileList 中的文件名是否不存在于 thumbList 中
func checkFilesNotInThumbList(fileList, thumbList []string) []string {
// 创建一个 map 来存储 thumbList 中的文件名
thumbMap := make(map[string]bool)
for _, thumb := range thumbList {
thumbMap[thumb] = true
}

// 检查 fileList 中的文件名是否在 thumbMap 中不存在
var result []string
for _, file := range fileList {
if _, exists := thumbMap[file]; !exists {
result = append(result, file)
}
}

return result
}
1 change: 1 addition & 0 deletions server/mian.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ func main() {

api.POST("/upload", UploadHandler)
api.POST("/store/deleteImage", DeleteImageHandler)
api.POST("/store/initThumb", GenerateThumb)
api.GET("/store/getStoreUrl", GetStoreUrlHandler)
api.GET("/store/getImageList", GetImageListHandler)
api.GET("/export", ExportHandler)
Expand Down
10 changes: 6 additions & 4 deletions server/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@ type Config struct {
}

type Result struct {
Code int `json:"code"`
Message string `json:"message"`
Url string `json:"url"`
BackupUrl string `json:"backupUrl"`
Code int `json:"code"`
Message string `json:"message"`
Url string `json:"url"`
BackupUrl string `json:"backupUrl"`
ThumFileUrl string `json:"thumFileUrl"`
}

type FileInfo struct {
Expand All @@ -25,6 +26,7 @@ type FileInfo struct {
FileType string `json:"fileType"`
FileUrl string `json:"fileUrl"`
BackupFileUrl string `json:"backupFileUrl"`
ThumFileUrl string `json:"thumFileUrl"`
}

// UploadDTO represents the data transfer object for uploading an image
Expand Down
36 changes: 32 additions & 4 deletions server/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"os"
"path/filepath"

"github.com/disintegration/imaging"
"github.com/golang/freetype"
)

Expand Down Expand Up @@ -152,10 +153,6 @@ func saveFile(fileInfo FileInfo, file multipart.File) error {
return nil
}

// PathExistsOrCreate 校验文件夹是否存在,不存在则创建
func PathExistsOrCreate(path string) {
}

func contains(slice []string, item string) bool {
for _, element := range slice {
if element == item {
Expand Down Expand Up @@ -235,3 +232,34 @@ func CompressFile(path string) (string, error) {

return generatePath, nil
}

// generateThumbnail generates a thumbnail for the uploaded image
func generateThumbnail(filePath string, fileName string) error {
srcPath := filepath.Join(filePath, fileName)
dstPath := filepath.Join(filePath+"/thumb/", fileName)

_, err := os.Stat(filePath + "/thumb/")
if err != nil {
err = os.Mkdir(filePath+"/thumb/", os.ModePerm)
if err != nil {
return fmt.Errorf("File Path Create Error: %w"+filePath, err)
}
}

// Open the source image file
srcImage, err := imaging.Open(srcPath)
if err != nil {
return fmt.Errorf("failed to open image: %v", err)
}

// Resize the image to width 100px preserving the aspect ratio
thumbnail := imaging.Resize(srcImage, 200, 0, imaging.Lanczos)

// Save the thumbnail image
err = imaging.Save(thumbnail, dstPath)
if err != nil {
return fmt.Errorf("failed to save thumbnail: %v", err)
}

return nil
}

0 comments on commit b5519c6

Please sign in to comment.