Last active
December 27, 2021 11:15
-
-
Save mizuneko/940bb4a29fa5ac80b72f6ea1812b924a to your computer and use it in GitHub Desktop.
[画像アップロード] 画像のアップロード処理をなるべく端折って記述したいときに #image
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package imgupload | |
import ( | |
"bytes" | |
"encoding/base64" | |
"errors" | |
"fmt" | |
"image" | |
"image/jpeg" | |
"image/png" | |
"io/ioutil" | |
"net/http" | |
"strconv" | |
"github.com/nfnt/resize" | |
) | |
type Image struct { | |
Filename string | |
ContentType string | |
Data []byte | |
Size int | |
} | |
// Save image to file. | |
func (i *Image) Save(filename string) error { | |
return ioutil.WriteFile(filename, i.Data, 0600) | |
} | |
// Convert image to base64 data uri. | |
func (i *Image) DataURI() string { | |
return fmt.Sprintf("data:%s;base64,%s", i.ContentType, base64.StdEncoding.EncodeToString(i.Data)) | |
} | |
// Write image to HTTP response. | |
func (i *Image) Write(w http.ResponseWriter) { | |
w.Header().Set("Content-Type", i.ContentType) | |
w.Header().Set("Content-Length", strconv.Itoa(i.Size)) | |
w.Write(i.Data) | |
} | |
// Create JPEG thumbnail from image. | |
func (i *Image) ThumbnailJPEG(width int, height int, quality int) (*Image, error) { | |
return ThumbnailJPEG(i, width, height, quality) | |
} | |
// Create PNG thumbnail from image. | |
func (i *Image) ThumbnailPNG(width int, height int) (*Image, error) { | |
return ThumbnailPNG(i, width, height) | |
} | |
// Limit the size of uploaded files, put this before imageupload.Process. | |
func LimitFileSize(maxSize int64, w http.ResponseWriter, r *http.Request) { | |
r.Body = http.MaxBytesReader(w, r.Body, maxSize) | |
} | |
func okContentType(contentType string) bool { | |
return contentType == "image/png" || contentType == "image/jpeg" || contentType == "image/gif" | |
} | |
// Process uploaded file into an image. | |
func Process(r *http.Request, field string) (*Image, error) { | |
file, info, err := r.FormFile(field) | |
if err != nil { | |
return nil, err | |
} | |
contentType := info.Header.Get("Content-Type") | |
if !okContentType(contentType) { | |
return nil, errors.New(fmt.Sprintf("Wrong content type: %s", contentType)) | |
} | |
bs, err := ioutil.ReadAll(file) | |
if err != nil { | |
return nil, err | |
} | |
_, _, err = image.Decode(bytes.NewReader(bs)) | |
if err != nil { | |
return nil, err | |
} | |
i := &Image{ | |
Filename: info.Filename, | |
ContentType: contentType, | |
Data: bs, | |
Size: len(bs), | |
} | |
return i, nil | |
} | |
// Create JPEG thumbnail. | |
func ThumbnailJPEG(i *Image, width int, height int, quality int) (*Image, error) { | |
img, _, err := image.Decode(bytes.NewReader(i.Data)) | |
thumbnail := resize.Thumbnail(uint(width), uint(height), img, resize.Lanczos3) | |
data := new(bytes.Buffer) | |
err = jpeg.Encode(data, thumbnail, &jpeg.Options{ | |
Quality: quality, | |
}) | |
if err != nil { | |
return nil, err | |
} | |
bs := data.Bytes() | |
t := &Image{ | |
Filename: "thumbnail.jpg", | |
ContentType: "image/jpeg", | |
Data: bs, | |
Size: len(bs), | |
} | |
return t, nil | |
} | |
// Create PNG thumbnail. | |
func ThumbnailPNG(i *Image, width int, height int) (*Image, error) { | |
img, _, err := image.Decode(bytes.NewReader(i.Data)) | |
thumbnail := resize.Thumbnail(uint(width), uint(height), img, resize.Lanczos3) | |
data := new(bytes.Buffer) | |
err = png.Encode(data, thumbnail) | |
if err != nil { | |
return nil, err | |
} | |
bs := data.Bytes() | |
t := &Image{ | |
Filename: "thumbnail.png", | |
ContentType: "image/png", | |
Data: bs, | |
Size: len(bs), | |
} | |
return t, nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment