/* —————————————————————————————————————————————————————————————————————————— Proyecto ImgResizer ————————————————————————————————————————————————————————————————————————————— Fichero main.go Package ImgResizer Autor Juan V. Navarro juanvnl@activething.com Creado 26/01/2026 ————————————————————————————————————————————————————————————————————————————— LICENSES AND TERMS OF USE ------------------------- This software is licensed under the Elastic License v2.0 (the "License"). For full terms and additional information regarding permitted and prohibited uses, please visit: https://activething.com/ATGO/licenses You may use, copy, modify, and redistribute this software internally within your organization for any purpose, including research, development, and testing, subject to the terms of this License. You may NOT, however, use, provide, distribute, or make this software available to any third party as part of a hosted service, SaaS offering, or commercial product without first obtaining a commercial license from Active Thing. You may combine this software with other code, provided that such combination does not circumvent the restrictions of this License. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. In no event shall the authors or copyright holders be liable for any claim, damages, or other liability arising from the use of this software. ————————————————————————————————————————————————————————————————————————————— Web : activething.com | activething.com/ImgResizer git : g.activething.com | github.com/activething/ImgResizer Correo : dev@activething.com ————————————————————————————————————————————————————————————————————————————— No deseo caminar sobre el agua", dijo Siddhartha. Que los antiguos chamanes se contenten con tales habilidades. —— Hermann Hesse, Siddhartha ————————————————————————————————————————————————————————————————————————————— Copyright (c) 2026 Active Thing ————————————————————————————————————————————————————————————————————————————— */ package main import ( "flag" "fmt" "image" "image/jpeg" "image/png" "log" "os" "path/filepath" "strings" "github.com/disintegration/imaging" // Decodificador Pure Go para WebP (No requiere CGO) _ "golang.org/x/image/webp" ) func main() { inputDir := flag.String("dir", "", "Directorio de origen") outputDir := flag.String("out", "", "Directorio de destino") width := flag.Int("width", 0, "Ancho (excluyente)") height := flag.Int("height", 0, "Alto (excluyente)") quality := flag.Int("calidad", 100, "Calidad (1-100)") configurarAyuda() flag.Parse() if *inputDir == "" || *outputDir == "" || (*width == 0 && *height == 0) { flag.Usage() return } if *width > 0 && *height > 0 { log.Fatal("Error: -width y -height son excluyentes.") } os.MkdirAll(*outputDir, 0755) files, _ := os.ReadDir(*inputDir) for _, file := range files { ext := strings.ToLower(filepath.Ext(file.Name())) if ext != ".jpg" && ext != ".jpeg" && ext != ".png" && ext != ".webp" { continue } fmt.Printf("Procesando %s... ", file.Name()) err := processImage(filepath.Join(*inputDir, file.Name()), filepath.Join(*outputDir, file.Name()), *width, *height, *quality) if err != nil { fmt.Printf("ERROR: %v\n", err) } else { fmt.Println("OK") } } } func processImage(src, dst string, w, h, q int) error { // 1. Abrir imagen (Soporta WebP, JPG, PNG gracias a los imports con _) f, err := os.Open(src) if err != nil { return err } defer f.Close() img, _, err := image.Decode(f) if err != nil { return err } // 2. Redimensionar resized := imaging.Resize(img, w, h, imaging.Lanczos) // 3. Guardar según extensión out, err := os.Create(dst) if err != nil { return err } defer out.Close() ext := strings.ToLower(filepath.Ext(dst)) switch ext { case ".jpg", ".jpeg": return jpeg.Encode(out, resized, &jpeg.Options{Quality: q}) case ".png": // El encoder estándar de Go es muy robusto return png.Encode(out, resized) case ".webp": // Si llegas aquí sin CGO, el programa dirá que no sabe codificar WebP // pero al menos el resto del programa COMPILARÁ y FUNCIONARÁ return fmt.Errorf("la escritura de WebP requiere CGO y un compilador de C (GCC)") default: return imaging.Save(resized, dst) } } func configurarAyuda() { flag.Usage = func() { fmt.Printf("\nUso: resizer -dir -out [-width | -height]\n") flag.PrintDefaults() } }