You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GoFiber中如何调整FormFile图片大小并保存到/public/images/目录

GoFiber上传FormData图片并调整尺寸保存实现方案

首先需要安装Go生态常用的图片处理库nfnt/resize,该库支持JPG、PNG等主流格式的缩放操作,安装命令:

go get github.com/nfnt/resize

核心实现逻辑

  • 调用c.FormFile获取上传文件后,先打开文件得到可读流
  • 根据文件后缀匹配对应解码器,将文件流解码为image.Image类型对象
  • 调用resize库完成尺寸调整,可自定义宽高和插值算法
  • 校验并创建目标存储目录/public/images/
  • 将调整后的图片按原格式编码写入到目标路径
  • 所有打开的文件流都要延迟关闭,避免资源泄漏

完整代码示例

导入依赖

import (
    "image"
    "image/jpeg"
    "image/png"
    "os"
    "path/filepath"
    "strings"

    "github.com/gofiber/fiber/v2"
    "github.com/nfnt/resize"
)

路由处理函数

func handleImageUpload(c *fiber.Ctx) error {
    // 获取上传的图片文件
    file, err := c.FormFile("image")
    if err != nil {
        return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
            "error": "无效的上传文件: " + err.Error(),
        })
    }

    // 打开上传文件得到可读流
    srcFile, err := file.Open()
    if err != nil {
        return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
            "error": "读取上传文件失败: " + err.Error(),
        })
    }
    defer srcFile.Close()

    // 根据文件后缀解码图片
    var img image.Image
    fileExt := strings.ToLower(filepath.Ext(file.Filename))
    switch fileExt {
    case ".jpg", ".jpeg":
        img, err = jpeg.Decode(srcFile)
    case ".png":
        img, err = png.Decode(srcFile)
    default:
        return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
            "error": "仅支持JPG、PNG格式的图片",
        })
    }
    if err != nil {
        return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
            "error": "图片解码失败: " + err.Error(),
        })
    }

    // 调整图片尺寸,示例固定宽度为800px,高度按原图比例自动适配
    // 若要固定高度,将第一个参数设为0,第二个参数传目标高度即可
    resizedImg := resize.Resize(800, 0, img, resize.Lanczos3)

    // 确保目标存储目录存在
    saveDir := "./public/images/"
    if err = os.MkdirAll(saveDir, 0755); err != nil {
        return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
            "error": "创建存储目录失败: " + err.Error(),
        })
    }

    // 生成保存路径,生产环境建议替换为随机文件名避免重名覆盖
    savePath := filepath.Join(saveDir, file.Filename)
    dstFile, err := os.Create(savePath)
    if err != nil {
        return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
            "error": "创建目标文件失败: " + err.Error(),
        })
    }
    defer dstFile.Close()

    // 编码写入调整后的图片
    switch fileExt {
    case ".jpg", ".jpeg":
        err = jpeg.Encode(dstFile, resizedImg, &jpeg.Options{Quality: 80})
    case ".png":
        err = png.Encode(dstFile, resizedImg)
    }
    if err != nil {
        return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
            "error": "保存调整后图片失败: " + err.Error(),
        })
    }

    return c.JSON(fiber.Map{
        "code": 0,
        "msg": "上传成功",
        "save_path": savePath,
    })
}

注意事项

  • 插值算法选择:resize.Lanczos3画质最优但性能稍低,对性能要求高的场景可以替换为resize.Bilinear
  • 文件名处理:示例直接使用原文件名,生产环境建议生成UUID加后缀的随机文件名,避免重名覆盖问题
  • 格式扩展:如果需要支持WebP等其他格式,只需引入对应格式的解码/编码库,新增对应switch分支即可
  • 权限配置:os.MkdirAll的权限参数0755可根据实际部署环境的目录权限要求调整

内容的提问来源于stack exchange,提问作者Saifullah Shahen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 21:18:03