Various changes to optimizeTextures
Fixed Multithreading, fixed a bug with alpha channels and changed the output format to tga.
This commit is contained in:
@@ -2,23 +2,70 @@ from PIL import Image
|
||||
import sys
|
||||
import os
|
||||
import time
|
||||
import numpy as np
|
||||
from multiprocessing import Pool, cpu_count, freeze_support
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
import threading
|
||||
|
||||
def process_image(args):
|
||||
input_path, export_dir, idx, total = args
|
||||
try:
|
||||
# Open image and check if it has alpha
|
||||
currentTex = Image.open(input_path)
|
||||
has_alpha = currentTex.mode == 'RGBA'
|
||||
was_resized = False
|
||||
|
||||
if currentTex.size <= (2048, 2048):
|
||||
print(f"{os.path.basename(input_path)} is already smaller than 2048x2048 ({idx}/{total})")
|
||||
return
|
||||
|
||||
# Downsize the image with a LANCZOS filter
|
||||
resizedTex = currentTex.resize((2048, 2048), Image.LANCZOS)
|
||||
if has_alpha:
|
||||
# Get the alpha channel
|
||||
r, g, b, a = currentTex.split()
|
||||
# Convert alpha to numpy array to check its values
|
||||
alpha_array = np.array(a)
|
||||
# Check if alpha channel is useful (contains values other than 0 or 255)
|
||||
has_useful_alpha = np.any((alpha_array > 0) & (alpha_array < 255))
|
||||
|
||||
if has_useful_alpha:
|
||||
# If alpha is useful, keep it
|
||||
if currentTex.size > (2048, 2048):
|
||||
resizedTex = currentTex.resize((2048, 2048), Image.LANCZOS)
|
||||
was_resized = True
|
||||
else:
|
||||
resizedTex = currentTex
|
||||
else:
|
||||
# If alpha is not useful (all black or all white), ignore it
|
||||
currentTex = currentTex.convert('RGB')
|
||||
if currentTex.size > (2048, 2048):
|
||||
resizedTex = currentTex.resize((2048, 2048), Image.LANCZOS)
|
||||
was_resized = True
|
||||
else:
|
||||
resizedTex = currentTex
|
||||
# Create new RGBA with full opacity
|
||||
rgba_image = Image.new('RGBA', resizedTex.size)
|
||||
rgba_image.paste(resizedTex, (0, 0))
|
||||
resizedTex = rgba_image
|
||||
else:
|
||||
# No alpha channel, just resize if needed
|
||||
if currentTex.size > (2048, 2048):
|
||||
resizedTex = currentTex.resize((2048, 2048), Image.LANCZOS)
|
||||
was_resized = True
|
||||
else:
|
||||
resizedTex = currentTex
|
||||
# Convert to RGBA with full opacity
|
||||
rgba_image = Image.new('RGBA', resizedTex.size)
|
||||
rgba_image.paste(resizedTex, (0, 0))
|
||||
resizedTex = rgba_image
|
||||
|
||||
output_path = os.path.join(export_dir, os.path.basename(input_path))
|
||||
resizedTex.save(output_path, optimize=True, quality=95)
|
||||
print(f"{os.path.basename(input_path)} successfully converted ({idx}/{total})")
|
||||
# Change the file extension to .tga
|
||||
output_filename = os.path.splitext(os.path.basename(input_path))[0] + '.tga'
|
||||
output_path = os.path.join(export_dir, output_filename)
|
||||
|
||||
# Save as TGA format with RLE compression
|
||||
resizedTex.save(output_path, format='TGA', rle=True)
|
||||
|
||||
# Print appropriate message based on whether the file was resized
|
||||
if was_resized:
|
||||
print(f"{os.path.basename(input_path)} optimized and converted to TGA ({idx}/{total})")
|
||||
else:
|
||||
print(f"{os.path.basename(input_path)} converted to TGA ({idx}/{total})")
|
||||
except Exception as e:
|
||||
print(f"Error processing {input_path} ({idx}/{total}): {e}")
|
||||
|
||||
@@ -46,10 +93,12 @@ def main():
|
||||
|
||||
# Check if running as a frozen executable
|
||||
if getattr(sys, 'frozen', False):
|
||||
# Avoid multiprocessing when frozen
|
||||
for args in args_list:
|
||||
process_image(args)
|
||||
# Use ThreadPoolExecutor when frozen
|
||||
max_workers = min(32, (os.cpu_count() or 1) + 4)
|
||||
with ThreadPoolExecutor(max_workers=max_workers) as executor:
|
||||
list(executor.map(process_image, args_list))
|
||||
else:
|
||||
# Use multiprocessing when running from console
|
||||
with Pool(processes=cpu_count()) as pool:
|
||||
pool.map(process_image, args_list)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user