我是靠谱客的博主 名字长了才好记,最近开发中收集的这篇文章主要介绍golang使用gin框架实现上传和水印完整代码,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

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框架实现上传和水印完整代码所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(205)

评论列表共有 0 条评论

立即
投稿
返回
顶部