feat: convert to go

This commit is contained in:
2026-01-30 10:40:19 +07:00
parent dcbb507b67
commit d3a0994edf
4 changed files with 195 additions and 98 deletions
+5
View File
@@ -0,0 +1,5 @@
module image-resizer
go 1.21
require golang.org/x/image v0.15.0
+2
View File
@@ -0,0 +1,2 @@
golang.org/x/image v0.15.0 h1:kOELfmgrmJlw4Cdb7g/QGuB3CvDrXbqEIww/pNtNBm8=
golang.org/x/image v0.15.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE=
+188
View File
@@ -0,0 +1,188 @@
package main
import (
"fmt"
"image"
"image/jpeg"
"image/png"
"os"
"path/filepath"
"strings"
_ "image/gif" // Register GIF decoder
_ "image/jpeg" // Register JPEG decoder
_ "image/png" // Register PNG decoder
"golang.org/x/image/bmp"
"golang.org/x/image/tiff"
)
// ResizeImage resizes an image to a specified percentage of its original size
func ResizeImage(inputPath, outputPath string, scalePercent int) error {
file, err := os.Open(inputPath)
if err != nil {
return fmt.Errorf("error opening file: %w", err)
}
defer file.Close()
img, _, err := image.Decode(file)
if err != nil {
return fmt.Errorf("error decoding image: %w", err)
}
// Get original dimensions
bounds := img.Bounds()
width := bounds.Dx()
height := bounds.Dy()
// Calculate new dimensions
newWidth := width * scalePercent / 100
newHeight := height * scalePercent / 100
// Create resized image using nearest neighbor (simple approach)
// For better quality, consider using github.com/nfnt/resize
resized := image.NewRGBA(image.Rect(0, 0, newWidth, newHeight))
// Simple resampling
for y := 0; y < newHeight; y++ {
for x := 0; x < newWidth; x++ {
srcX := x * width / newWidth
srcY := y * height / newHeight
resized.Set(x, y, img.At(srcX, srcY))
}
}
// Create output file
outFile, err := os.Create(outputPath)
if err != nil {
return fmt.Errorf("error creating output file: %w", err)
}
defer outFile.Close()
// Encode based on format or output extension
ext := strings.ToLower(filepath.Ext(outputPath))
switch ext {
case ".jpg", ".jpeg":
err = jpeg.Encode(outFile, resized, &jpeg.Options{Quality: 95})
case ".png":
err = png.Encode(outFile, resized)
case ".gif":
// For GIF, we'd need additional encoding support
err = jpeg.Encode(outFile, resized, &jpeg.Options{Quality: 95})
case ".bmp":
err = bmp.Encode(outFile, resized)
case ".tiff", ".tif":
err = tiff.Encode(outFile, resized, nil)
case ".webp":
// WebP encoding is complex, save as PNG instead
err = png.Encode(outFile, resized)
default:
// Default to PNG
err = png.Encode(outFile, resized)
}
if err != nil {
return fmt.Errorf("error encoding image: %w", err)
}
fmt.Printf("Resized: %s -> %s\n", inputPath, outputPath)
fmt.Printf(" Original: %dx%d, New: %dx%d\n", width, height, newWidth, newHeight)
return nil
}
// ResizeImagesInFolder resizes all images in a folder and its subfolders
func ResizeImagesInFolder(folderPath string, scalePercent int, outputFolder string, overwrite bool) error {
// Supported image formats
imageExtensions := map[string]bool{
".jpg": true,
".jpeg": true,
".png": true,
".gif": true,
".bmp": true,
".tiff": true,
".webp": true,
}
folderPath = filepath.Clean(folderPath)
var outputBasePath string
if overwrite {
outputBasePath = folderPath
} else {
if outputFolder == "" {
outputBasePath = filepath.Join(folderPath, "resized")
} else {
outputBasePath = filepath.Clean(outputFolder)
}
}
// Walk through all files and subdirectories
err := filepath.Walk(folderPath, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
// Skip directories
if info.IsDir() {
return nil
}
// Check if file has supported image extension
ext := strings.ToLower(filepath.Ext(path))
if !imageExtensions[ext] {
return nil
}
// Determine output path
var outputPath string
if overwrite {
outputPath = path
} else {
// Get relative path from folderPath
relPath, err := filepath.Rel(folderPath, path)
if err != nil {
return fmt.Errorf("error getting relative path: %w", err)
}
outputPath = filepath.Join(outputBasePath, relPath)
// Create output directory if it doesn't exist
outputDir := filepath.Dir(outputPath)
if err := os.MkdirAll(outputDir, 0755); err != nil {
return fmt.Errorf("error creating output directory: %w", err)
}
}
// Resize the image
if err := ResizeImage(path, outputPath, scalePercent); err != nil {
fmt.Printf("Error processing %s: %v\n", path, err)
}
return nil
})
return err
}
func main() {
// Configuration
folderPath := `D:\kvtm\kvtm\client\res\common\ui\EventTet2026` // Change to your folder path
scalePercent := 50 // Resize to 50% of original size
overwrite := true // Set to false to save to output folder instead
fmt.Printf("Image Resizer - Scaling to %d%%\n", scalePercent)
fmt.Printf("Source folder: %s\n", folderPath)
if overwrite {
fmt.Println("Mode: Overwriting original images")
} else {
fmt.Println("Mode: Saving to output folder")
}
fmt.Println(strings.Repeat("-", 50))
if err := ResizeImagesInFolder(folderPath, scalePercent, "", overwrite); err != nil {
fmt.Printf("Error: %v\n", err)
os.Exit(1)
}
fmt.Println(strings.Repeat("-", 50))
fmt.Println("Done!")
}
-98
View File
@@ -1,98 +0,0 @@
import os
from pathlib import Path
from PIL import Image
def resize_image(input_path, output_path, scale_percent):
"""
Resize an image to a specified percentage of its original size.
Args:
input_path: Path to the input image
output_path: Path where the resized image will be saved
scale_percent: Percentage to scale the image (e.g., 50 for 50%)
"""
try:
with Image.open(input_path) as img:
# Calculate new dimensions
width, height = img.size
new_width = int(width * scale_percent / 100)
new_height = int(height * scale_percent / 100)
# Resize using high-quality resampling
resized_img = img.resize((new_width, new_height), Image.Resampling.LANCZOS)
# Save the resized image
resized_img.save(output_path)
print(f"Resized: {input_path} -> {output_path}")
print(f" Original: {width}x{height}, New: {new_width}x{new_height}")
except Exception as e:
print(f"Error processing {input_path}: {e}")
def resize_images_in_folder(
folder_path, scale_percent, output_folder=None, overwrite=False
):
"""
Resize all images in a folder and its subfolders.
Args:
folder_path: Path to the folder containing images
scale_percent: Percentage to scale the images (e.g., 50 for 50%)
output_folder: Optional output folder. If None, creates a 'resized' subfolder
overwrite: If True, overwrites original images. If False, saves to output folder
"""
# Supported image formats
image_extensions = {".jpg", ".jpeg", ".png", ".gif", ".bmp", ".tiff", ".webp"}
# Setup output path
folder_path = Path(folder_path)
if overwrite:
output_base_path = folder_path
else:
if output_folder is None:
output_folder = folder_path / "resized"
else:
output_folder = Path(output_folder)
# Process all files in folder and subfolders
for root, dirs, files in os.walk(folder_path):
root_path = Path(root)
# Create relative path structure for output
if not overwrite:
relative_path = root_path.relative_to(folder_path)
current_output_path = output_folder / relative_path
current_output_path.mkdir(parents=True, exist_ok=True)
else:
current_output_path = root_path
# Process each image file
for file in files:
file_path = root_path / file
file_ext = file_path.suffix.lower()
if file_ext in image_extensions:
if overwrite:
output_path = file_path
else:
output_path = current_output_path / file
resize_image(file_path, output_path, scale_percent)
if __name__ == "__main__":
# Configuration
FOLDER_PATH = "D:\\kvtm\\kvtm\\client\\res\\common\\ui\\EventTet2026" # Current directory - change to your folder path
SCALE_PERCENT = 50 # Resize to 50% of original size
print(f"Image Resizer - Scaling to {SCALE_PERCENT}%")
print(f"Source folder: {FOLDER_PATH}")
print("Mode: Overwriting original images")
print("-" * 50)
resize_images_in_folder(FOLDER_PATH, SCALE_PERCENT, overwrite=True)
print("-" * 50)
print("Done!")