初始
This commit is contained in:
209
api/v1/common/coryCommon/imgData.go
Normal file
209
api/v1/common/coryCommon/imgData.go
Normal file
@ -0,0 +1,209 @@
|
||||
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)
|
||||
}
|
Reference in New Issue
Block a user