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
相关产品推荐
相关产品推荐

