package image import ( "bytes" "encoding/base64" "image" _ "image/gif" _ "image/jpeg" _ "image/png" "net/http" "regexp" "strings" "sync" _ "golang.org/x/image/webp" ) // Regex to match data URL pattern var dataURLPattern = regexp.MustCompile(`data:image/([^;]+);base64,(.*)`) 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 } func GetImageSizeFromUrl(url string) (width int, height int, err error) { isImage, err := IsImageUrl(url) if !isImage { return } 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 } func GetImageFromUrl(url string) (mimeType string, data string, err error) { // Check if the URL is a data URL matches := dataURLPattern.FindStringSubmatch(url) if len(matches) == 3 { // URL is a data URL mimeType = "image/" + matches[1] data = matches[2] return } 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 } var ( reg = regexp.MustCompile(`data:image/([^;]+);base64,`) ) var readerPool = sync.Pool{ New: func() interface{} { return &bytes.Reader{} }, } func GetImageSizeFromBase64(encoded string) (width int, height int, err error) { decoded, err := base64.StdEncoding.DecodeString(reg.ReplaceAllString(encoded, "")) if err != nil { 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 } 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) }