add image conversion for telegram
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
package media
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const maxTelegramPhotoSize = 10 * 1024 * 1024 // 10 MB
|
||||
|
||||
// CompressImage compresses an image if it exceeds Telegram's 10 MB photo limit.
|
||||
// It uses ImageMagick's magick command to convert via stdin/stdout.
|
||||
// Returns the (possibly compressed) data, updated filename, and any error.
|
||||
func CompressImage(ctx context.Context, data []byte, filename string) (out []byte, outName string, err error) {
|
||||
if len(data) <= maxTelegramPhotoSize {
|
||||
return data, filename, nil
|
||||
}
|
||||
|
||||
// First attempt: just re-encode as JPEG with quality 85
|
||||
out, err = runMagick(ctx, data, "-quality", "85")
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("compress image: %w", err)
|
||||
}
|
||||
|
||||
newFilename := replaceExt(filename, ".jpg")
|
||||
|
||||
if len(out) <= maxTelegramPhotoSize {
|
||||
return out, newFilename, nil
|
||||
}
|
||||
|
||||
// Second attempt: resize to 50% and quality 85
|
||||
out, err = runMagick(ctx, data, "-resize", "50%", "-quality", "85")
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("compress image with resize: %w", err)
|
||||
}
|
||||
|
||||
if len(out) > maxTelegramPhotoSize {
|
||||
return nil, "", fmt.Errorf("image still too large after compression (%d bytes)", len(out))
|
||||
}
|
||||
|
||||
return out, newFilename, nil
|
||||
}
|
||||
|
||||
func runMagick(ctx context.Context, data []byte, args ...string) ([]byte, error) {
|
||||
cmdArgs := append([]string{"-"}, args...)
|
||||
cmdArgs = append(cmdArgs, "jpeg:-")
|
||||
|
||||
cmd := exec.CommandContext(ctx, "magick", cmdArgs...)
|
||||
cmd.Stdin = bytes.NewReader(data)
|
||||
|
||||
out, err := cmd.Output()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("magick: %w", err)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func replaceExt(filename, newExt string) string {
|
||||
if i := strings.LastIndex(filename, "."); i >= 0 {
|
||||
return filename[:i] + newExt
|
||||
}
|
||||
return filename + newExt
|
||||
}
|
||||
Reference in New Issue
Block a user