package util import ( "errors" "image" "image/gif" "image/jpeg" "image/png" "os" "path/filepath" "strings" "github.com/nfnt/resize" ) func ResizeImage(imagePath string, width int, height int) (outputPath string, err error) { // 打开源图片文件 file, err := os.Open(imagePath) if err != nil { return "", err } defer file.Close() // 解码图片 var img image.Image var decodeErr error ext := strings.ToLower(filepath.Ext(imagePath)) switch ext { case ".jpg", ".jpeg": img, decodeErr = jpeg.Decode(file) case ".png": img, decodeErr = png.Decode(file) default: return "", errors.New("unsupported image format") } if decodeErr != nil { return "", decodeErr } // 调整图片大小 resized := resize.Resize(uint(width), uint(height), img, resize.Lanczos3) // 创建输出文件 outputPath = strings.TrimSuffix(imagePath, ext) + "_resized" + ext out, err := os.Create(outputPath) if err != nil { return "", err } defer out.Close() // 根据文件扩展名选择编码方式 switch ext { case ".jpg", ".jpeg": return outputPath, jpeg.Encode(out, resized, nil) case ".png": return outputPath, png.Encode(out, resized) default: return "", errors.New("unsupported image format") } } // ResizeImageByMaxWidth 按最大宽度缩放图片,保持宽高比 func ResizeImageByMaxWidth(imagePath string, maxWidth uint) (outputPath string, err error) { // 打开源图片文件 file, err := os.Open(imagePath) if err != nil { return "", err } defer file.Close() // 解码图片 var img image.Image var decodeErr error ext := strings.ToLower(filepath.Ext(imagePath)) switch ext { case ".jpg", ".jpeg": img, decodeErr = jpeg.Decode(file) case ".png": img, decodeErr = png.Decode(file) default: return "", errors.New("unsupported image format") } if decodeErr != nil { return "", decodeErr } // 计算缩放后的尺寸,保持宽高比 // 传入0作为高度,resize包会自动计算等比例的高度 resized := resize.Resize(maxWidth, 0, img, resize.Lanczos3) // 创建输出文件 outputPath = strings.TrimSuffix(imagePath, ext) + "_resized" + ext out, err := os.Create(outputPath) if err != nil { return "", err } defer out.Close() // 根据文件扩展名选择编码方式 switch ext { case ".jpg", ".jpeg": return outputPath, jpeg.Encode(out, resized, nil) case ".png": return outputPath, png.Encode(out, resized) default: return "", errors.New("unsupported image format") } } // ResizeImageByMaxHeight2File 按最大高度缩放图片,保持宽高比 func ResizeImageByMaxHeight2File(imagePath string, maxHeight uint) (outputPath string, err error) { // 打开源图片文件 file, err := os.Open(imagePath) if err != nil { return "", err } defer file.Close() // 解码图片 var img image.Image var decodeErr error var gifImg *gif.GIF ext := strings.ToLower(filepath.Ext(imagePath)) switch ext { case ".jpg", ".jpeg": img, decodeErr = jpeg.Decode(file) case ".png": img, decodeErr = png.Decode(file) case ".gif": gifImg, decodeErr = gif.DecodeAll(file) default: return "", errors.New("unsupported image format") } if decodeErr != nil { return "", decodeErr } // 计算缩放后的尺寸,保持宽高比 // 传入0作为宽度,resize包会自动计算等比例的宽度 var resized image.Image if gifImg == nil { resized = resize.Resize(0, maxHeight, img, resize.Lanczos3) } else { for i, frame := range gifImg.Image { resized = resize.Resize(0, maxHeight, frame, resize.Lanczos3) gifImg.Image[i] = resized.(*image.Paletted) } } // 创建输出文件 outputPath = strings.TrimSuffix(imagePath, ext) + "_resized" + ext out, err := os.Create(outputPath) if err != nil { return "", err } defer out.Close() // 根据文件扩展名选择编码方式 switch ext { case ".jpg", ".jpeg": return outputPath, jpeg.Encode(out, resized, nil) case ".png": return outputPath, png.Encode(out, resized) case ".gif": return outputPath, gif.EncodeAll(out, gifImg) default: return "", errors.New("unsupported image format") } } func ResizeImageByMaxHeight2Image(imagePath string, maxHeight uint) (output []image.Image, delay []int, err error) { // 打开源图片文件 file, err := os.Open(imagePath) if err != nil { return nil, nil, err } defer file.Close() // 解码图片 var img image.Image var decodeErr error var gifImg *gif.GIF ext := strings.ToLower(filepath.Ext(imagePath)) switch ext { case ".jpg", ".jpeg": img, decodeErr = jpeg.Decode(file) case ".png": img, decodeErr = png.Decode(file) case ".gif": gifImg, decodeErr = gif.DecodeAll(file) default: return nil, nil, errors.New("unsupported image format") } if decodeErr != nil { return nil, nil, decodeErr } // 计算缩放后的尺寸,保持宽高比 // 传入0作为宽度,resize包会自动计算等比例的宽度 var resized []image.Image if gifImg == nil { resized = []image.Image{resize.Resize(0, maxHeight, img, resize.Lanczos3)} } else { for _, frame := range gifImg.Image { img := resize.Resize(0, maxHeight, frame, resize.Lanczos3) resized = append(resized, img) } delay = gifImg.Delay } return resized, delay, nil } func GetResizedIamgePathByOrgPath(orgPath string) string { ext := strings.ToLower(filepath.Ext(orgPath)) return strings.TrimSuffix(orgPath, ext) + "_resized" + ext }