package coryCommon import ( "bytes" "encoding/base64" "errors" "fmt" "image" _ "image/gif" _ "image/jpeg" _ "image/png" "io/ioutil" "net/url" "os" "path/filepath" "strconv" "strings" ) const ( MinShortEdge = 15 MaxLongEdge = 4096 MaxSize = 1024 * 1024 // 4MB SupportedExts = ".jpg .jpeg .png .bmp" ) func ImgDataBase64(filePath string) (err error, encodedURL string) { file, err := os.Open(filePath) if err != nil { fmt.Println("打开图像文件失败:", err) err = errors.New("打开图像文件失败") return } defer file.Close() fileInfo, err := file.Stat() if err != nil { fmt.Println("读取图像文件信息失败:", err) err = errors.New("读取图像文件信息失败") return } fileSize := fileInfo.Size() if fileSize > MaxSize { fmt.Println("图像文件大小超过限制:", fileSize) err = errors.New("图像文件大小超过限制") return } imgData, err := ioutil.ReadAll(file) if err != nil { fmt.Println("读取图像文件内容失败:", err) err = errors.New("读取图像文件内容失败") return } bounds, format, err := image.DecodeConfig(bytes.NewReader(imgData)) if err != nil { fmt.Println("解码图像配置失败:", err) err = errors.New("解码图像配置失败") return } if format != "jpeg" && format != "jpg" && format != "png" && format != "bmp" { fmt.Println("不支持的图像格式:", format) //err = errors.New("不支持的图像格式") err = errors.New("支持的图像格式为:jpg、png、gif、bmp") return } width := bounds.Width height := bounds.Height shortEdge := width if height < width { shortEdge = height } if shortEdge < MinShortEdge { fmt.Println("图像尺寸的最短边小于要求:", shortEdge) str := "图像尺寸的最短边小于要求:" + strconv.Itoa(shortEdge) err = errors.New(str) return } if width > MaxLongEdge || height > MaxLongEdge { fmt.Println("图像尺寸的最长边超过限制:", width, height) str := "图像尺寸的最长边超过限制:" + strconv.Itoa(width) + strconv.Itoa(height) err = errors.New(str) return } // Base64编码图像数据 encodedStr := base64.StdEncoding.EncodeToString(imgData) // URL编码 //urlEncodedStr := url.QueryEscape(encodedStr) //fmt.Println("Base64编码并URL编码后的图像数据:", urlEncodedStr) return err, encodedStr } /* EncodeAndUrlEncodeImage 图片文件的绝对路径 功能: 图像数据,base64编码后进行urlencode,需去掉编码头(data:image/jpeg;base64, )要求base64编码和urlencode后大小不超过N兆,最短边至少15px,最长边最大4096px,支持jpg/jpeg/png/bmp格式 */ func EncodeAndUrlEncodeImage(filePath string, size int64) (string, error) { // 检查文件是否存在 _, err := os.Stat(filePath) if os.IsNotExist(err) { return "", fmt.Errorf("文件 %s 不存在", filePath) } // 检查文件大小 fileSize := getFileSize(filePath) if fileSize > (size * MaxSize) { return "", fmt.Errorf("文件大小超过限制") } // 检查图像尺寸 img, err := loadImage(filePath) if err != nil { return "", fmt.Errorf("无法加载图像: %s", err) } bounds := img.Bounds() if !isValidSize(bounds) { return "", fmt.Errorf("图像尺寸不符合要求") } // 读取文件 fileData, err := ioutil.ReadFile(filePath) if err != nil { return "", fmt.Errorf("无法读取文件: %s", err) } // 获取文件后缀名 ext := filepath.Ext(filePath) // 检查是否支持的文件格式 if !isSupportedFormat(ext) { return "", fmt.Errorf("不支持的文件格式") } // 将图像数据进行 base64 编码 encodedData := base64.StdEncoding.EncodeToString(fileData) // 去掉编码头(如:"data:image/jpeg;base64,") encodedData = removeEncodingHeader(encodedData, ext) //// 对 base64 编码后的数据进行 URL 编码 //encodedData = urlEncode(encodedData) return encodedData, nil } func getFileSize(filePath string) int64 { fileInfo, err := os.Stat(filePath) if err != nil { return 0 } return fileInfo.Size() } func loadImage(filePath string) (image.Image, error) { file, err := os.Open(filePath) if err != nil { return nil, err } defer file.Close() img, _, err := image.Decode(file) if err != nil { return nil, err } return img, nil } func isValidSize(bounds image.Rectangle) bool { width := bounds.Dx() height := bounds.Dy() if width < MinShortEdge || height < MinShortEdge { return false } if width > MaxLongEdge || height > MaxLongEdge { return false } return true } func isSupportedFormat(ext string) bool { ext = strings.ToLower(ext) return strings.Contains(SupportedExts, ext) } func removeEncodingHeader(encodedData string, ext string) string { header := fmt.Sprintf("data:image/%s;base64,", ext[1:]) if strings.HasPrefix(encodedData, header) { encodedData = strings.TrimPrefix(encodedData, header) } return encodedData } func urlEncode(data string) string { return url.PathEscape(data) }