qq_bot/util/picture.go

227 lines
5.3 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
}