You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
lib/image/image.go

97 lines
1.7 KiB
Go

package image
import (
"bytes"
"image/gif"
"image/jpeg"
"image/png"
"io"
"mime/multipart"
"os"
)
// CompressImage 壓縮圖片至指定位置
func CompressImage(input interface{}, output string) (err error) {
var file io.Reader
var fileToClose io.Closer
switch v := input.(type) {
case string:
f, err := os.Open(v)
if err != nil {
return err
}
file = f
fileToClose = f
defer func() {
if fileToClose != nil {
_ = fileToClose.Close()
}
_ = os.Remove(v)
}()
case *multipart.FileHeader:
f, err := v.Open()
if err != nil {
return err
}
file = f
fileToClose = f
defer func() {
if fileToClose != nil {
_ = fileToClose.Close()
}
}()
}
var buf bytes.Buffer
if _, err = io.Copy(&buf, file); err != nil {
return err
}
bs := buf.Bytes()
var ext string
if _, err = jpeg.Decode(bytes.NewReader(bs)); err == nil {
ext = "jpg"
} else if _, err = png.Decode(bytes.NewReader(bs)); err == nil {
ext = "png"
} else if _, err = gif.Decode(bytes.NewReader(bs)); err == nil {
ext = "gif"
}
outputFile, err := os.Create(output)
if err != nil {
return err
}
defer func() {
if outputFile != nil {
_ = outputFile.Close()
}
}()
switch ext {
case "jpg":
img, err := jpeg.Decode(bytes.NewReader(bs))
if err != nil {
return err
}
return jpeg.Encode(outputFile, img, &jpeg.Options{Quality: 70})
case "png":
img, err := png.Decode(bytes.NewReader(bs))
if err != nil {
return err
}
encoder := png.Encoder{CompressionLevel: png.BestCompression}
return encoder.Encode(outputFile, img)
case "gif":
img, err := gif.DecodeAll(bytes.NewReader(bs))
if err != nil {
return err
}
return gif.EncodeAll(outputFile, img)
default:
_, err = outputFile.Write(bs)
return err
}
}