2023-12-10 11:39:46 +00:00
|
|
|
package image
|
|
|
|
|
|
|
|
import (
|
2023-12-24 07:35:56 +00:00
|
|
|
"bytes"
|
|
|
|
"encoding/base64"
|
2023-12-10 11:39:46 +00:00
|
|
|
"image"
|
|
|
|
_ "image/gif"
|
|
|
|
_ "image/jpeg"
|
|
|
|
_ "image/png"
|
|
|
|
"net/http"
|
|
|
|
"regexp"
|
|
|
|
"strings"
|
2023-12-24 07:35:56 +00:00
|
|
|
"sync"
|
2023-12-10 11:39:46 +00:00
|
|
|
|
|
|
|
_ "golang.org/x/image/webp"
|
|
|
|
)
|
|
|
|
|
2023-12-24 10:54:32 +00:00
|
|
|
func IsImageUrl(url string) (bool, error) {
|
|
|
|
resp, err := http.Head(url)
|
|
|
|
if err != nil {
|
|
|
|
return false, err
|
|
|
|
}
|
|
|
|
if !strings.HasPrefix(resp.Header.Get("Content-Type"), "image/") {
|
|
|
|
return false, nil
|
|
|
|
}
|
|
|
|
return true, nil
|
|
|
|
}
|
|
|
|
|
2023-12-10 11:39:46 +00:00
|
|
|
func GetImageSizeFromUrl(url string) (width int, height int, err error) {
|
2023-12-24 10:54:32 +00:00
|
|
|
isImage, err := IsImageUrl(url)
|
|
|
|
if !isImage {
|
|
|
|
return
|
|
|
|
}
|
2023-12-10 11:39:46 +00:00
|
|
|
resp, err := http.Get(url)
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
defer resp.Body.Close()
|
|
|
|
img, _, err := image.DecodeConfig(resp.Body)
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
return img.Width, img.Height, nil
|
|
|
|
}
|
|
|
|
|
2023-12-24 10:54:32 +00:00
|
|
|
func GetImageFromUrl(url string) (mimeType string, data string, err error) {
|
|
|
|
isImage, err := IsImageUrl(url)
|
|
|
|
if !isImage {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
resp, err := http.Get(url)
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
defer resp.Body.Close()
|
|
|
|
buffer := bytes.NewBuffer(nil)
|
|
|
|
_, err = buffer.ReadFrom(resp.Body)
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
mimeType = resp.Header.Get("Content-Type")
|
|
|
|
data = base64.StdEncoding.EncodeToString(buffer.Bytes())
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2023-12-10 11:39:46 +00:00
|
|
|
var (
|
|
|
|
reg = regexp.MustCompile(`data:image/([^;]+);base64,`)
|
|
|
|
)
|
|
|
|
|
2023-12-24 07:35:56 +00:00
|
|
|
var readerPool = sync.Pool{
|
|
|
|
New: func() interface{} {
|
|
|
|
return &bytes.Reader{}
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2023-12-10 11:39:46 +00:00
|
|
|
func GetImageSizeFromBase64(encoded string) (width int, height int, err error) {
|
2023-12-24 07:35:56 +00:00
|
|
|
decoded, err := base64.StdEncoding.DecodeString(reg.ReplaceAllString(encoded, ""))
|
2023-12-10 11:39:46 +00:00
|
|
|
if err != nil {
|
2023-12-24 07:35:56 +00:00
|
|
|
return 0, 0, err
|
|
|
|
}
|
|
|
|
|
|
|
|
reader := readerPool.Get().(*bytes.Reader)
|
|
|
|
defer readerPool.Put(reader)
|
|
|
|
reader.Reset(decoded)
|
|
|
|
|
|
|
|
img, _, err := image.DecodeConfig(reader)
|
|
|
|
if err != nil {
|
|
|
|
return 0, 0, err
|
2023-12-10 11:39:46 +00:00
|
|
|
}
|
2023-12-24 07:35:56 +00:00
|
|
|
|
2023-12-10 11:39:46 +00:00
|
|
|
return img.Width, img.Height, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func GetImageSize(image string) (width int, height int, err error) {
|
|
|
|
if strings.HasPrefix(image, "data:image/") {
|
|
|
|
return GetImageSizeFromBase64(image)
|
|
|
|
}
|
|
|
|
return GetImageSizeFromUrl(image)
|
|
|
|
}
|