Raggaer
Raggaer

Reputation: 3318

Go image upload

I am currently uploading an image to my server doing the following:

func (base *GuildController) GuildLogo(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
    ...
    logo, _, err := req.FormFile("logo")
    defer logo.Close()
    logoGif, format, err := image.Decode(logo)
    if err != nil {
        base.Error = "Error while decoding your guild logo"
        return
    }
    logoImage, err := os.Create(pigo.Config.String("template")+"/public/guilds/"+ps.ByName("name")+".gif")
    if err != nil {
        base.Error = "Error while trying to open guild logo image"
        return
    }
    defer logoImage.Close()
    //resizedLogo := resize.Resize(64, 64, logoGif, resize.Lanczos3)
    err = gif.Encode(logoImage, logoGif, &gif.Options{
        256,
        nil,
        nil,
    })
    if err != nil {
        base.Error = "Error while encoding your guild logo"
        return
    }
    ...
}

So everything is working good. But gifs lose the animation.

For example here is a gif I want to upload

enter image description here

And here is the saved one

enter image description here

Not sure what I am doing wrong

Upvotes: 3

Views: 1171

Answers (2)

MD Golam Rakib
MD Golam Rakib

Reputation: 144

Image upload using gin framework.

First create your project directory and run the command "go get -u github.com/gin-gonic/gin"

Then Create a assets/upload directory inside root directory.

Add the following code in main.go file.

func main() {
    r := gin.Default()
    r.Static("/assets", "./assets")
    r.LoadHTMLGlob("templates/*")
    r.MaxMultipartMemory = 8 << 20 // 8 MiB

    r.GET("/", func(c *gin.Context) {
        c.HTML(http.StatusOK, "index.html", gin.H{})
    })

    r.POST("/upload", func(c *gin.Context) {
        // Get the file
        file, err := c.FormFile("image")

        if err != nil {
            c.HTML(http.StatusBadRequest, "index.html", gin.H{
                "error": "Failed to upload image",
            })
            return
        }

        filePath := "assets/uploads/" + file.Filename

        // Upload the file to specific folder.
        err = c.SaveUploadedFile(file, filePath)

        if err != nil {
            c.HTML(http.StatusBadRequest, "index.html", gin.H{
                "error": "Failed to upload image",
            })
            return
        }

        c.HTML(http.StatusOK, "index.html", gin.H{
            "image": "/" + filePath,
        })
    })

    r.Run() // listen and serve on 0.0.0.0:8080
}

Then create a templates directory and create a index.html file inside the directory and paste the following code...

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Golang File Upload</title>
</head>
<body>
    {{ if .image }}
        <img src="{{ .image }}" alt="">
    {{ end }}
    <form action="/upload" method="post" enctype="multipart/form-data">
        <input type="file" name="image" id="">
        <input type="submit" value="Submit">
    </form>

    {{ if .error }}
        <p>{{ .error }}</p>
    {{ end }}
</body>
</html>

At last run the application using "go run main.go" and test.

Upvotes: 0

AkiRoss
AkiRoss

Reputation: 12273

As hinted in the comments, you are just working with one frame:

func Decode(r io.Reader) (image.Image, error) Decode reads a GIF image from r and returns the first embedded image as an image.Image.

But you need

func DecodeAll(r io.Reader) (*GIF, error) DecodeAll reads a GIF image from r and returns the sequential frames and timing information.

and

func EncodeAll(w io.Writer, g *GIF) error EncodeAll writes the images in g to w in GIF format with the given loop count and delay between frames.

Look at this post for details.

Here's an example that slows down the image to 0.5s each frame:

package main

import (
    "image/gif"
    "os"
)

func main() {
    logo, err := os.Open("yay.gif")
    if err != nil {
        panic(err)
    }
    defer logo.Close()

    inGif, err := gif.DecodeAll(logo)
    if err != nil {
        panic(err)
    }

    outGif, err := os.Create("done.gif")
    if err != nil {
        panic(err)
    }
    defer outGif.Close()

    for i := range inGif.Delay {
        inGif.Delay[i] = 50
    }
    if err := gif.EncodeAll(outGif, inGif); err != nil {
        panic(err)
    }
}

Results:

Original Image Slowed-down version

Side note

Even if in my browser (Firefox) I see the output image animated, and I can see the the frames in The GIMP, I cannot see it animated on my desktop viewers (gifview, comix). I do not know (yet) what is the cause of this.

Upvotes: 3

Related Questions