main.go完整代码:
package main
import (
"fmt"
"image"
"image/draw"
"image/gif"
"image/jpeg"
"image/png"
"io"
"log"
"net/http"
"os"
"path/filepath"
"github.com/gin-gonic/gin"
)
var supportedImageTypes = map[string]bool{
"image/jpeg": true,
"image/png": true,
"image/gif": true,
}
func main() {
r := gin.Default()
// 确保上传目录存在
if err := os.MkdirAll("./uploads", os.ModePerm); err != nil {
log.Fatalf("无法创建上传目录: %v", err)
}
r.POST("/upload", uploadAndWatermark)
r.Run(":8080")
}
func uploadAndWatermark(c *gin.Context) {
file, err := c.FormFile("file")
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "未收到文件"})
return
}
src, err := file.Open()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "无法读取上传的文件"})
return
}
defer src.Close()
buf := make([]byte, 512)
if _, err := src.Read(buf); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "无法读取文件内容"})
return
}
fileType := http.DetectContentType(buf)
if _, err := src.Seek(0, 0); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "无法重置文件指针"})
return
}
if !supportedImageTypes[fileType] {
c.JSON(http.StatusBadRequest, gin.H{"error": "不支持的文件类型"})
return
}
filename := filepath.Base(file.Filename)
uploadPath := "./uploads/" + filename
out, err := os.Create(uploadPath)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "无法保存上传的文件"})
return
}
defer out.Close()
if _, err = io.Copy(out, src); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "无法保存上传的文件内容"})
return
}
watermarkedPath := "./uploads/watermarked_" + filename
if err := addWatermark(uploadPath, "./watermark.png", watermarkedPath); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "无法添加水印", "details": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{
"message": "文件上传并添加水印成功",
"file": watermarkedPath,
})
}
func addWatermark(srcPath, watermarkPath, destPath string) error {
srcImg, srcFormat, err := loadImage(srcPath)
if err != nil {
return fmt.Errorf("加载源图像失败: %v", err)
}
watermarkImg, watermarkFormat, err := loadImage(watermarkPath)
if err != nil {
return fmt.Errorf("加载水印图像失败: %v", err)
}
if !supportedImageTypes["image/"+watermarkFormat] {
return fmt.Errorf("不支持的水印图像类型: %s", watermarkFormat)
}
offset := image.Pt(
srcImg.Bounds().Dx()-watermarkImg.Bounds().Dx()-10,
srcImg.Bounds().Dy()-watermarkImg.Bounds().Dy()-10,
)
b := srcImg.Bounds()
m := image.NewRGBA(b)
draw.Draw(m, b, srcImg, image.Point{}, draw.Src)
draw.Draw(m, watermarkImg.Bounds().Add(offset), watermarkImg, image.Point{}, draw.Over)
outFile, err := os.Create(destPath)
if err != nil {
return fmt.Errorf("创建输出文件失败: %v", err)
}
defer outFile.Close()
switch srcFormat {
case "jpeg":
err = jpeg.Encode(outFile, m, &jpeg.Options{Quality: 90})
case "png":
err = png.Encode(outFile, m)
case "gif":
err = gif.Encode(outFile, m, nil)
default:
return fmt.Errorf("不支持的源图像格式: %s", srcFormat)
}
if err != nil {
return fmt.Errorf("保存水印图像失败: %v", err)
}
return nil
}
func loadImage(path string) (image.Image, string, error) {
file, err := os.Open(path)
if err != nil {
return nil, "", err
}
defer file.Close()
img, format, err := image.Decode(file)
if err != nil {
return nil, "", err
}
return img, format, nil
}最后
以上就是名字长了才好记最近收集整理的关于golang使用gin框架实现上传和水印完整代码的全部内容,更多相关golang使用gin框架实现上传和水印完整代码内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复