|
|
|
|
package main
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"bytes"
|
|
|
|
|
"encoding/base64"
|
|
|
|
|
"flag"
|
|
|
|
|
"fmt"
|
|
|
|
|
"image"
|
|
|
|
|
"image/jpeg"
|
|
|
|
|
"image/png"
|
|
|
|
|
"os"
|
|
|
|
|
"path/filepath"
|
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
|
|
"golang.org/x/image/draw"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type Config struct {
|
|
|
|
|
dir string
|
|
|
|
|
width int
|
|
|
|
|
height int
|
|
|
|
|
quality int
|
|
|
|
|
typescript bool
|
|
|
|
|
tsgroup bool
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
|
cfg := parseFlags()
|
|
|
|
|
|
|
|
|
|
// Verificar que el directorio existe
|
|
|
|
|
if _, err := os.Stat(cfg.dir); os.IsNotExist(err) {
|
|
|
|
|
fmt.Printf("Error: El directorio '%s' no existe\n", cfg.dir)
|
|
|
|
|
os.Exit(1)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Validar que solo se especifica width o height, no ambos
|
|
|
|
|
if cfg.width > 0 && cfg.height > 0 {
|
|
|
|
|
fmt.Println("Error: No puedes especificar -width y -height simultáneamente")
|
|
|
|
|
fmt.Println("La relación de aspecto se mantiene automáticamente")
|
|
|
|
|
os.Exit(1)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Validar que no se usen -ts y -tsgroup juntos
|
|
|
|
|
if cfg.typescript && cfg.tsgroup {
|
|
|
|
|
fmt.Println("Error: No puedes usar -ts y -tsgroup simultáneamente")
|
|
|
|
|
os.Exit(1)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Leer archivos del directorio
|
|
|
|
|
entries, err := os.ReadDir(cfg.dir)
|
|
|
|
|
if err != nil {
|
|
|
|
|
fmt.Printf("Error al leer el directorio: %v\n", err)
|
|
|
|
|
os.Exit(1)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Si es tsgroup, procesar todas las imágenes en un solo archivo
|
|
|
|
|
if cfg.tsgroup {
|
|
|
|
|
processTsGroup(entries, cfg)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Procesamiento individual
|
|
|
|
|
processed := 0
|
|
|
|
|
for _, entry := range entries {
|
|
|
|
|
if entry.IsDir() {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Verificar si es una imagen soportada
|
|
|
|
|
ext := strings.ToLower(filepath.Ext(entry.Name()))
|
|
|
|
|
if ext != ".jpg" && ext != ".jpeg" && ext != ".png" {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inputPath := filepath.Join(cfg.dir, entry.Name())
|
|
|
|
|
|
|
|
|
|
var outputPath string
|
|
|
|
|
if cfg.typescript {
|
|
|
|
|
outputPath = strings.TrimSuffix(inputPath, ext) + ".b64.ts"
|
|
|
|
|
} else {
|
|
|
|
|
outputPath = strings.TrimSuffix(inputPath, ext) + ".base64"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fmt.Printf("Procesando: %s\n", entry.Name())
|
|
|
|
|
|
|
|
|
|
if err := processImage(inputPath, outputPath, cfg); err != nil {
|
|
|
|
|
fmt.Printf(" Error: %v\n", err)
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fmt.Printf(" ✓ Generado: %s\n", filepath.Base(outputPath))
|
|
|
|
|
processed++
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fmt.Printf("\n%d imágenes procesadas correctamente\n", processed)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func parseFlags() Config {
|
|
|
|
|
cfg := Config{}
|
|
|
|
|
|
|
|
|
|
flag.StringVar(&cfg.dir, "dir", "", "Directorio con las imágenes (requerido)")
|
|
|
|
|
flag.IntVar(&cfg.width, "width", 0, "Ancho máximo en píxeles (mantiene proporción)")
|
|
|
|
|
flag.IntVar(&cfg.height, "height", 0, "Alto máximo en píxeles (mantiene proporción)")
|
|
|
|
|
flag.IntVar(&cfg.quality, "quality", 80, "Calidad JPEG (1-100)")
|
|
|
|
|
flag.BoolVar(&cfg.typescript, "ts", false, "Generar archivos TypeScript individuales (.b64.ts)")
|
|
|
|
|
flag.BoolVar(&cfg.tsgroup, "tsgroup", false, "Generar un único archivo TypeScript con todas las imágenes")
|
|
|
|
|
|
|
|
|
|
flag.Usage = func() {
|
|
|
|
|
fmt.Fprintf(os.Stderr, "\n╔════════════════════════════════════════════════════════════════════╗\n")
|
|
|
|
|
fmt.Fprintf(os.Stderr, "║ Procesador de Imágenes a Base64 / TypeScript ║\n")
|
|
|
|
|
fmt.Fprintf(os.Stderr, "╚════════════════════════════════════════════════════════════════════╝\n\n")
|
|
|
|
|
|
|
|
|
|
fmt.Fprintf(os.Stderr, "DESCRIPCIÓN:\n")
|
|
|
|
|
fmt.Fprintf(os.Stderr, " Redimensiona imágenes y las convierte a Base64 o archivos TypeScript.\n")
|
|
|
|
|
fmt.Fprintf(os.Stderr, " Mantiene la relación de aspecto automáticamente.\n\n")
|
|
|
|
|
|
|
|
|
|
fmt.Fprintf(os.Stderr, "USO:\n")
|
|
|
|
|
fmt.Fprintf(os.Stderr, " %s -dir <directorio> [opciones]\n\n", os.Args[0])
|
|
|
|
|
|
|
|
|
|
fmt.Fprintf(os.Stderr, "PARÁMETROS:\n")
|
|
|
|
|
fmt.Fprintf(os.Stderr, " -dir string\n")
|
|
|
|
|
fmt.Fprintf(os.Stderr, " Directorio con las imágenes a procesar (REQUERIDO)\n")
|
|
|
|
|
fmt.Fprintf(os.Stderr, " Formatos soportados: JPG, JPEG, PNG\n\n")
|
|
|
|
|
|
|
|
|
|
fmt.Fprintf(os.Stderr, " -width int\n")
|
|
|
|
|
fmt.Fprintf(os.Stderr, " Ancho máximo en píxeles (mantiene proporción)\n")
|
|
|
|
|
fmt.Fprintf(os.Stderr, " No se puede usar junto con -height\n")
|
|
|
|
|
fmt.Fprintf(os.Stderr, " Por defecto: 800\n\n")
|
|
|
|
|
|
|
|
|
|
fmt.Fprintf(os.Stderr, " -height int\n")
|
|
|
|
|
fmt.Fprintf(os.Stderr, " Alto máximo en píxeles (mantiene proporción)\n")
|
|
|
|
|
fmt.Fprintf(os.Stderr, " No se puede usar junto con -width\n\n")
|
|
|
|
|
|
|
|
|
|
fmt.Fprintf(os.Stderr, " -quality int\n")
|
|
|
|
|
fmt.Fprintf(os.Stderr, " Calidad de compresión JPEG (1-100)\n")
|
|
|
|
|
fmt.Fprintf(os.Stderr, " Por defecto: 80\n\n")
|
|
|
|
|
|
|
|
|
|
fmt.Fprintf(os.Stderr, " -ts\n")
|
|
|
|
|
fmt.Fprintf(os.Stderr, " Generar archivos TypeScript individuales (.b64.ts)\n")
|
|
|
|
|
fmt.Fprintf(os.Stderr, " Formato: export const nombre = \"data:image/jpeg;base64,...\"\n")
|
|
|
|
|
fmt.Fprintf(os.Stderr, " No se puede usar junto con -tsgroup\n\n")
|
|
|
|
|
|
|
|
|
|
fmt.Fprintf(os.Stderr, " -tsgroup\n")
|
|
|
|
|
fmt.Fprintf(os.Stderr, " Generar un único archivo TypeScript con todas las imágenes\n")
|
|
|
|
|
fmt.Fprintf(os.Stderr, " Archivo: nombre-directorio.b64.ts\n")
|
|
|
|
|
fmt.Fprintf(os.Stderr, " No se puede usar junto con -ts\n\n")
|
|
|
|
|
|
|
|
|
|
fmt.Fprintf(os.Stderr, " -h, -help\n")
|
|
|
|
|
fmt.Fprintf(os.Stderr, " Muestra esta ayuda\n\n")
|
|
|
|
|
|
|
|
|
|
fmt.Fprintf(os.Stderr, "EJEMPLOS:\n")
|
|
|
|
|
fmt.Fprintf(os.Stderr, " # Uso básico (ancho 800px por defecto)\n")
|
|
|
|
|
fmt.Fprintf(os.Stderr, " %s -dir ./imagenes\n\n", os.Args[0])
|
|
|
|
|
|
|
|
|
|
fmt.Fprintf(os.Stderr, " # Redimensionar a 2480px de ancho para PDF A4 a 300 DPI\n")
|
|
|
|
|
fmt.Fprintf(os.Stderr, " %s -dir ./imagenes -width 2480\n\n", os.Args[0])
|
|
|
|
|
|
|
|
|
|
fmt.Fprintf(os.Stderr, " # Redimensionar por altura con calidad máxima\n")
|
|
|
|
|
fmt.Fprintf(os.Stderr, " %s -dir ./imagenes -height 3508 -quality 95\n\n", os.Args[0])
|
|
|
|
|
|
|
|
|
|
fmt.Fprintf(os.Stderr, " # Generar archivos TypeScript individuales\n")
|
|
|
|
|
fmt.Fprintf(os.Stderr, " %s -dir ./imagenes -width 800 -ts\n\n", os.Args[0])
|
|
|
|
|
|
|
|
|
|
fmt.Fprintf(os.Stderr, " # Generar un único archivo TypeScript con todas las imágenes\n")
|
|
|
|
|
fmt.Fprintf(os.Stderr, " %s -dir ./imagenes -width 800 -tsgroup\n\n", os.Args[0])
|
|
|
|
|
|
|
|
|
|
fmt.Fprintf(os.Stderr, " # Dimensiones para visualización web\n")
|
|
|
|
|
fmt.Fprintf(os.Stderr, " %s -dir ./imagenes -width 1240 -quality 85\n\n", os.Args[0])
|
|
|
|
|
|
|
|
|
|
fmt.Fprintf(os.Stderr, "DIMENSIONES RECOMENDADAS PARA PDF:\n")
|
|
|
|
|
fmt.Fprintf(os.Stderr, " ┌─────────────────────┬─────────┬─────────────────┐\n")
|
|
|
|
|
fmt.Fprintf(os.Stderr, " │ Uso │ Ancho │ DPI │\n")
|
|
|
|
|
fmt.Fprintf(os.Stderr, " ├─────────────────────┼─────────┼─────────────────┤\n")
|
|
|
|
|
fmt.Fprintf(os.Stderr, " │ Impresión A4 │ 2480 px │ 300 DPI │\n")
|
|
|
|
|
fmt.Fprintf(os.Stderr, " │ Pantalla A4 │ 1240 px │ 150 DPI │\n")
|
|
|
|
|
fmt.Fprintf(os.Stderr, " │ Web/Email │ 800 px │ 96 DPI │\n")
|
|
|
|
|
fmt.Fprintf(os.Stderr, " └─────────────────────┴─────────┴─────────────────┘\n\n")
|
|
|
|
|
|
|
|
|
|
fmt.Fprintf(os.Stderr, "NOTAS:\n")
|
|
|
|
|
fmt.Fprintf(os.Stderr, " • La relación de aspecto se mantiene automáticamente\n")
|
|
|
|
|
fmt.Fprintf(os.Stderr, " • No puedes usar -width y -height simultáneamente\n")
|
|
|
|
|
fmt.Fprintf(os.Stderr, " • No puedes usar -ts y -tsgroup simultáneamente\n")
|
|
|
|
|
fmt.Fprintf(os.Stderr, " • Las imágenes más pequeñas que el tamaño especificado no se agrandan\n")
|
|
|
|
|
fmt.Fprintf(os.Stderr, " • Archivos generados:\n")
|
|
|
|
|
fmt.Fprintf(os.Stderr, " - Sin flags: nombreoriginal.base64\n")
|
|
|
|
|
fmt.Fprintf(os.Stderr, " - Con -ts: nombreoriginal.b64.ts (uno por imagen)\n")
|
|
|
|
|
fmt.Fprintf(os.Stderr, " - Con -tsgroup: nombre-directorio.b64.ts (todas las imágenes)\n\n")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
flag.Parse()
|
|
|
|
|
|
|
|
|
|
if cfg.dir == "" {
|
|
|
|
|
flag.Usage()
|
|
|
|
|
os.Exit(1)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Valores por defecto si no se especifica nada
|
|
|
|
|
if cfg.width == 0 && cfg.height == 0 {
|
|
|
|
|
cfg.width = 800
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if cfg.quality < 1 || cfg.quality > 100 {
|
|
|
|
|
fmt.Println("Error: La calidad debe estar entre 1 y 100")
|
|
|
|
|
os.Exit(1)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return cfg
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func processImage(inputPath, outputPath string, cfg Config) error {
|
|
|
|
|
// Abrir imagen
|
|
|
|
|
file, err := os.Open(inputPath)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("error al abrir archivo: %w", err)
|
|
|
|
|
}
|
|
|
|
|
defer file.Close()
|
|
|
|
|
|
|
|
|
|
// Decodificar imagen
|
|
|
|
|
img, format, err := image.Decode(file)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("error al decodificar imagen: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Redimensionar imagen
|
|
|
|
|
resizedImg := resizeImage(img, cfg.width, cfg.height)
|
|
|
|
|
|
|
|
|
|
// Convertir a bytes
|
|
|
|
|
var buf bytes.Buffer
|
|
|
|
|
switch format {
|
|
|
|
|
case "jpeg", "jpg":
|
|
|
|
|
err = jpeg.Encode(&buf, resizedImg, &jpeg.Options{Quality: cfg.quality})
|
|
|
|
|
case "png":
|
|
|
|
|
err = png.Encode(&buf, resizedImg)
|
|
|
|
|
default:
|
|
|
|
|
err = jpeg.Encode(&buf, resizedImg, &jpeg.Options{Quality: cfg.quality})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("error al codificar imagen: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Convertir a base64
|
|
|
|
|
base64Str := base64.StdEncoding.EncodeToString(buf.Bytes())
|
|
|
|
|
|
|
|
|
|
// Preparar contenido según el formato
|
|
|
|
|
var content string
|
|
|
|
|
if cfg.typescript {
|
|
|
|
|
// Generar nombre de variable desde el nombre del archivo
|
|
|
|
|
varName := generateVarName(filepath.Base(inputPath))
|
|
|
|
|
content = fmt.Sprintf("export const %s = \"data:image/jpeg;base64,%s\"\n", varName, base64Str)
|
|
|
|
|
} else {
|
|
|
|
|
content = base64Str
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Guardar archivo
|
|
|
|
|
err = os.WriteFile(outputPath, []byte(content), 0644)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("error al guardar archivo: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func resizeImage(img image.Image, maxW, maxH int) image.Image {
|
|
|
|
|
bounds := img.Bounds()
|
|
|
|
|
width := bounds.Dx()
|
|
|
|
|
height := bounds.Dy()
|
|
|
|
|
|
|
|
|
|
var newWidth, newHeight int
|
|
|
|
|
|
|
|
|
|
if maxW > 0 && maxH == 0 {
|
|
|
|
|
// Solo se especificó ancho
|
|
|
|
|
ratio := float64(height) / float64(width)
|
|
|
|
|
newWidth = maxW
|
|
|
|
|
newHeight = int(float64(newWidth) * ratio)
|
|
|
|
|
} else if maxH > 0 && maxW == 0 {
|
|
|
|
|
// Solo se especificó alto
|
|
|
|
|
ratio := float64(width) / float64(height)
|
|
|
|
|
newHeight = maxH
|
|
|
|
|
newWidth = int(float64(newHeight) * ratio)
|
|
|
|
|
} else {
|
|
|
|
|
// Valores por defecto (no debería llegar aquí por validación)
|
|
|
|
|
ratio := float64(width) / float64(height)
|
|
|
|
|
newWidth = maxW
|
|
|
|
|
newHeight = int(float64(newWidth) / ratio)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Si la imagen ya es más pequeña, no redimensionar
|
|
|
|
|
if width <= newWidth && height <= newHeight {
|
|
|
|
|
return img
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Crear nueva imagen
|
|
|
|
|
dst := image.NewRGBA(image.Rect(0, 0, newWidth, newHeight))
|
|
|
|
|
|
|
|
|
|
// Redimensionar con interpolación de alta calidad
|
|
|
|
|
draw.CatmullRom.Scale(dst, dst.Bounds(), img, bounds, draw.Over, nil)
|
|
|
|
|
|
|
|
|
|
return dst
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func generateVarName(filename string) string {
|
|
|
|
|
// Remover extensión
|
|
|
|
|
name := strings.TrimSuffix(filename, filepath.Ext(filename))
|
|
|
|
|
|
|
|
|
|
// Reemplazar caracteres no válidos para variables
|
|
|
|
|
name = strings.Map(func(r rune) rune {
|
|
|
|
|
if (r >= 'a' && r <= 'z') || (r >= 'A' && r <= 'Z') || (r >= '0' && r <= '9') {
|
|
|
|
|
return r
|
|
|
|
|
}
|
|
|
|
|
return '_'
|
|
|
|
|
}, name)
|
|
|
|
|
|
|
|
|
|
// Si empieza con número, añadir prefijo
|
|
|
|
|
if len(name) > 0 && name[0] >= '0' && name[0] <= '9' {
|
|
|
|
|
name = "img_" + name
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Si está vacío, usar nombre por defecto
|
|
|
|
|
if name == "" {
|
|
|
|
|
name = "image"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return name
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func processTsGroup(entries []os.DirEntry, cfg Config) {
|
|
|
|
|
// Obtener nombre del directorio
|
|
|
|
|
dirName := filepath.Base(cfg.dir)
|
|
|
|
|
outputPath := filepath.Join(cfg.dir, dirName+".b64.ts")
|
|
|
|
|
|
|
|
|
|
var tsContent strings.Builder
|
|
|
|
|
tsContent.WriteString("// Imágenes generadas automáticamente\n\n")
|
|
|
|
|
|
|
|
|
|
processed := 0
|
|
|
|
|
for _, entry := range entries {
|
|
|
|
|
if entry.IsDir() {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Verificar si es una imagen soportada
|
|
|
|
|
ext := strings.ToLower(filepath.Ext(entry.Name()))
|
|
|
|
|
if ext != ".jpg" && ext != ".jpeg" && ext != ".png" {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inputPath := filepath.Join(cfg.dir, entry.Name())
|
|
|
|
|
fmt.Printf("Procesando: %s\n", entry.Name())
|
|
|
|
|
|
|
|
|
|
// Procesar imagen a base64
|
|
|
|
|
base64Str, err := imageToBase64(inputPath, cfg)
|
|
|
|
|
if err != nil {
|
|
|
|
|
fmt.Printf(" Error: %v\n", err)
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Generar nombre de variable
|
|
|
|
|
varName := generateVarName(entry.Name())
|
|
|
|
|
|
|
|
|
|
// Añadir al contenido TypeScript
|
|
|
|
|
tsContent.WriteString(fmt.Sprintf("export const %s = \"data:image/jpeg;base64,%s\"\n\n", varName, base64Str))
|
|
|
|
|
|
|
|
|
|
fmt.Printf(" ✓ Añadido: %s\n", varName)
|
|
|
|
|
processed++
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if processed == 0 {
|
|
|
|
|
fmt.Println("No se encontraron imágenes para procesar")
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Guardar archivo
|
|
|
|
|
err := os.WriteFile(outputPath, []byte(tsContent.String()), 0644)
|
|
|
|
|
if err != nil {
|
|
|
|
|
fmt.Printf("Error al guardar archivo: %v\n", err)
|
|
|
|
|
os.Exit(1)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fmt.Printf("\n✓ Archivo generado: %s\n", filepath.Base(outputPath))
|
|
|
|
|
fmt.Printf("%d imágenes procesadas correctamente\n", processed)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func imageToBase64(inputPath string, cfg Config) (string, error) {
|
|
|
|
|
// Abrir imagen
|
|
|
|
|
file, err := os.Open(inputPath)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return "", fmt.Errorf("error al abrir archivo: %w", err)
|
|
|
|
|
}
|
|
|
|
|
defer file.Close()
|
|
|
|
|
|
|
|
|
|
// Decodificar imagen
|
|
|
|
|
img, format, err := image.Decode(file)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return "", fmt.Errorf("error al decodificar imagen: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Redimensionar imagen
|
|
|
|
|
resizedImg := resizeImage(img, cfg.width, cfg.height)
|
|
|
|
|
|
|
|
|
|
// Convertir a bytes
|
|
|
|
|
var buf bytes.Buffer
|
|
|
|
|
switch format {
|
|
|
|
|
case "jpeg", "jpg":
|
|
|
|
|
err = jpeg.Encode(&buf, resizedImg, &jpeg.Options{Quality: cfg.quality})
|
|
|
|
|
case "png":
|
|
|
|
|
err = png.Encode(&buf, resizedImg)
|
|
|
|
|
default:
|
|
|
|
|
err = jpeg.Encode(&buf, resizedImg, &jpeg.Options{Quality: cfg.quality})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
return "", fmt.Errorf("error al codificar imagen: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Convertir a base64
|
|
|
|
|
return base64.StdEncoding.EncodeToString(buf.Bytes()), nil
|
|
|
|
|
}
|