big update: added reactions, groups, media share
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
package media
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"image"
|
||||
_ "image/gif"
|
||||
"image/jpeg"
|
||||
_ "image/png"
|
||||
|
||||
"golang.org/x/image/draw"
|
||||
"golang.org/x/image/webp"
|
||||
)
|
||||
|
||||
const maxUploadSize = 25 << 20 // 25 MiB
|
||||
|
||||
// IsImage reports whether the content type is a decodable image format.
|
||||
func IsImage(contentType string) bool {
|
||||
switch contentType {
|
||||
case "image/jpeg", "image/png", "image/gif", "image/webp":
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// Generate returns a JPEG thumbnail of at most maxDim on its larger side.
|
||||
// It returns nil for non-images or when the source is already small enough.
|
||||
func Generate(ctx context.Context, r *bytes.Reader, contentType string, maxDim int) ([]byte, error) {
|
||||
if !IsImage(contentType) {
|
||||
return nil, nil
|
||||
}
|
||||
if err := ctx.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
src, err := decodeImage(r, contentType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
bounds := src.Bounds()
|
||||
w, h := bounds.Dx(), bounds.Dy()
|
||||
if w <= maxDim && h <= maxDim {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
scale := float64(maxDim) / float64(max(w, h))
|
||||
nw, nh := int(float64(w)*scale), int(float64(h)*scale)
|
||||
if nw < 1 {
|
||||
nw = 1
|
||||
}
|
||||
if nh < 1 {
|
||||
nh = 1
|
||||
}
|
||||
|
||||
dst := image.NewRGBA(image.Rect(0, 0, nw, nh))
|
||||
draw.BiLinear.Scale(dst, dst.Bounds(), src, bounds, draw.Over, nil)
|
||||
|
||||
if err := ctx.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
if err := jpeg.Encode(&buf, dst, &jpeg.Options{Quality: 80}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
func decodeImage(r *bytes.Reader, contentType string) (image.Image, error) {
|
||||
if contentType == "image/webp" {
|
||||
return webp.Decode(r)
|
||||
}
|
||||
img, _, err := image.Decode(r)
|
||||
return img, err
|
||||
}
|
||||
|
||||
func max(a, b int) int {
|
||||
if a > b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
Reference in New Issue
Block a user