import os
import shutil
class TimelineDetector:
"""
The functionality of this class is identical to the original code you provided.
It is responsible for analyzing the content of a single file to determine its type.
"""
def __init__(self, file_path: str = None):
self.file_path = file_path
def is_scene_data(self, content_str: str) -> bool:
"""Checks if the content is scene data."""
return "KStudio" in content_str
def check_timeline(self, content_str: str) -> tuple[str, str, float]:
"""
Checks the timeline type and returns the timeline status and duration.
Returns:
tuple (timeline_status, image_type, duration)
timeline_status: "has_timeline" or "no_timeline"
image_type: "dynamic", "static", or None
duration: float or None
"""
if "timeline" in content_str: # First, check if "timeline" exists
# Check if it's static (it's static if "Timeline" is not present)
if "Timeline" not in content_str:
return "has_timeline", "static", None
else:
# It's dynamic, now check for duration
if "duration" in content_str:
dur_pos = content_str.find("duration")
search_pos = dur_pos + len("duration")
while search_pos < len(content_str):
if content_str[search_pos].isdigit():
num_start = search_pos
num_end = num_start
while num_end < len(content_str) and (content_str[num_end].isdigit() or content_str[num_end] == '.'):
num_end += 1
try:
duration = float(content_str[num_start:num_end])
return "has_timeline", "dynamic", duration
except ValueError:
return "has_timeline", "dynamic", None
search_pos += 1
return "has_timeline", "dynamic", None
return "no_timeline", None, None
def batch_process_animated_images(input_dir: str, output_dir: str):
"""
Iterates through the input directory, finds all dynamic images,
and moves them to the output directory.
Args:
input_dir (str): The path to the source folder containing .png files.
output_dir (str): The path to the destination folder for dynamic images.
"""
# Ensure the output directory exists, create it if it doesn't
if not os.path.exists(output_dir):
os.makedirs(output_dir)
print(f"Created output directory: {output_dir}")
detector = TimelineDetector()
animated_image_count = 0
print(f"Starting scan of input directory: {input_dir}")
print("Operation Mode: Move Files")
# Iterate over all files in the input directory
for filename in os.listdir(input_dir):
# Only process .png files
if filename.lower().endswith(".png"):
file_path = os.path.join(input_dir, filename)
# Skip subdirectories, process only files
if not os.path.isfile(file_path):
continue
try:
with open(file_path, 'rb') as f:
content = f.read()
content_str = content.decode('utf-8', errors='ignore')
# 1. Check if it's valid scene data
if not detector.is_scene_data(content_str):
print(f"Skipped (not scene data): {filename}")
continue
# 2. Check the timeline status
timeline_status, image_type, duration = detector.check_timeline(content_str)
# 3. If it's a dynamic image with a timeline, move it
if timeline_status == "has_timeline" and image_type == "dynamic":
destination_path = os.path.join(output_dir, filename)
# Use shutil.move to move the file
shutil.move(file_path, destination_path)
duration_info = f" (duration: {duration}s)" if duration is not None else ""
print(f"Found dynamic image, moved: {filename}{duration_info}")
animated_image_count += 1
else:
print(f"Skipped (not a dynamic image): {filename}")
except Exception as e:
print(f"Error processing file {filename}: {e}")
print("\nBatch processing complete.")
print(f"Total files moved: {animated_image_count} dynamic images to {output_dir}")
def main():
# ==================================================================
# === Please configure your paths here ===
# ==================================================================
# Replace "Please_paste_your_full_input_directory_path_here" with the path to the folder containing your .png files.
# Example (Windows): "C:\\Users\\YourUser\\Desktop\\input"
# Example (macOS): "/Users/YourUser/Desktop/input"
INPUT_DIRECTORY = "Please_paste_your_full_input_directory_path_here"
# Replace "Please_paste_your_full_output_directory_path_here" with the path to the folder where you want to store the dynamic images.
# Example (Windows): "C:\\Users\\YourUser\\Desktop\\output_animated"
# Example (macOS): "/Users/YourUser/Desktop/output_animated"
OUTPUT_DIRECTORY = "Please_paste_your_full_output_directory_path_here"
# ==================================================================
# === End of configuration. Please do not modify below this line. ===
# ==================================================================
# Check if the paths have been set
if "Please_paste" in INPUT_DIRECTORY or "Please_paste" in OUTPUT_DIRECTORY:
print("Error: You have not configured the input or output directory paths.")
print("Please open this .py file with a text editor and fill in the values for INPUT_DIRECTORY and OUTPUT_DIRECTORY.")
input("\nPress Enter to exit...")
return
# Check if the input path exists and is a directory
if not os.path.isdir(INPUT_DIRECTORY):
print(f"Error: The input path '{INPUT_DIRECTORY}' is not a valid directory.")
input("\nPress Enter to exit...")
return
# Check if the input and output paths are the same
if os.path.abspath(INPUT_DIRECTORY) == os.path.abspath(OUTPUT_DIRECTORY):
print(f"Error: The input and output directories cannot be the same path.")
input("\nPress Enter to exit...")
return
# Execute the batch process
batch_process_animated_images(INPUT_DIRECTORY, OUTPUT_DIRECTORY)
input("\nAll tasks are complete. Press Enter to exit...")
if __name__ == "__main__":
main()