mirror of
https://github.com/tiennm99/MTTools.git
synced 2026-08-26 07:26:49 +00:00
feat: convert to go
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
module image-resizer
|
||||
|
||||
go 1.21
|
||||
|
||||
require golang.org/x/image v0.15.0
|
||||
@@ -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=
|
||||
@@ -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!")
|
||||
}
|
||||
@@ -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!")
|
||||
Reference in New Issue
Block a user