48 lines
1.6 KiB
Go
48 lines
1.6 KiB
Go
package processor
|
||
|
||
import (
|
||
"bytes"
|
||
"image"
|
||
"image/jpeg"
|
||
_ "image/png" // Для поддержки декодирования PNG
|
||
|
||
"github.com/disintegration/imaging"
|
||
)
|
||
|
||
// ProcessImage обрабатывает картинку в зависимости от типа загрузки
|
||
// mode может быть: "avatar", "chat", "raw"
|
||
func ProcessImage(fileBytes []byte, mode string) ([]byte, string, error) {
|
||
// Если пользователь отправил "как файл" (без сжатия)
|
||
if mode == "raw" {
|
||
return fileBytes, "image/jpeg", nil // В идеале тут нужно определять mime-type по байтам
|
||
}
|
||
|
||
// Декодируем исходную картинку
|
||
img, _, err := image.Decode(bytes.NewReader(fileBytes))
|
||
if err != nil {
|
||
return nil, "", err
|
||
}
|
||
|
||
var processedImg image.Image
|
||
|
||
switch mode {
|
||
case "avatar":
|
||
// Telegram делает аватарки квадратными (например, 500x500)
|
||
processedImg = imaging.Fill(img, 500, 500, imaging.Center, imaging.Lanczos)
|
||
case "chat":
|
||
// Ограничиваем максимальный размер для чата (например, 1280px по большей стороне),
|
||
// сохраняя пропорции
|
||
processedImg = imaging.Fit(img, 1280, 1280, imaging.Lanczos)
|
||
default:
|
||
processedImg = img
|
||
}
|
||
|
||
// Кодируем результат в сжатый JPEG (качество 80 - отличный баланс размера и качества)
|
||
buf := new(bytes.Buffer)
|
||
err = jpeg.Encode(buf, processedImg, &jpeg.Options{Quality: 80})
|
||
if err != nil {
|
||
return nil, "", err
|
||
}
|
||
|
||
return buf.Bytes(), "image/jpeg", nil
|
||
} |