Bilder-Stapelverarbeitung
Kurze Vorwarnung dass dies hier überwiegend KI-generiertes Zeug ist. Hat funktioniert, muss aber nicht erneut funktionieren. Es ist wichtig dass ihr in Grundzügen nachvollziehen könnt, was die Scripts tun, auch wenn sie generiert sind.
Pastet diese Scripts z.B. in eine KI rein und lasst sie euch erklären. Easy as that... Nur kurz schildern wer ihr seid und was ihr beruflich macht und warum ihr euch jetzt unbedingt das Script anschauen müsst.
Generatoren: ChatGPT, Claude.ai, manchmal Llama, je nachdem was so passte.
Umgang mit auch größeren Anzahlen an Bildern. Teils getestet an einem ganzen Terabyte Bildern.
Sortierung nach Bildgröße
Fest definierte Größe
ChatGPT 3.5 als Hilfestellung
Skript sammelt Bilder die kleiner als festgelegte Auflösung sind in einem anderen Ordner und belässt die, die größer sind im Ordner.
Das Beispiel hier trennt Bilder >4K von denen die es nicht sind.
param (
[string]$SourceFolder = "C:\Path\to\SourceFolder",
[string]$DestinationFolder = "C:\Path\to\DestinationFolder",
[int]$MinWidth = 3840,
[int]$MinHeight = 2160
)
# Create the destination folder if it doesn't exist
if (-not (Test-Path $DestinationFolder)) {
New-Item -ItemType Directory -Path $DestinationFolder | Out-Null
}
# Get all image files in the source folder and its subfolders
$images = Get-ChildItem -Path $SourceFolder -Filter "*.jpg" -File -Recurse
$totalImages = $images.Count
$processedImages = 0
# Process each image file
foreach ($image in $images) {
Write-Host "Processing $($image.FullName)"
# Use .NET classes to read image dimensions
$imageStream = New-Object System.IO.FileStream($image.FullName, [System.IO.FileMode]::Open)
$imageBitmap = New-Object System.Drawing.Bitmap($imageStream)
$width = $imageBitmap.Width
$height = $imageBitmap.Height
$imageStream.Close()
# Check if the image is smaller than the specified dimensions
if ($width -lt $MinWidth -or $height -lt $MinHeight) {
$destinationPath = Join-Path -Path $DestinationFolder -ChildPath $image.Name
Write-Host "Moving $($image.FullName) to $destinationPath"
Move-Item -Path $image.FullName -Destination $destinationPath
}
$processedImages++
$progress = [math]::Round(($processedImages / $totalImages) * 100, 2)
Write-Progress -Activity "Moving images" -Status "Progress: $progress%" -PercentComplete $progress
}
Write-Progress -Activity "Moving images" -Status "Progress: 100%" -PercentComplete 100
Write-Host "Image move complete!"
Auswahldialoge für Auflösung und Ordner
Claude 3.5 Sonnet
- Mindestauflösung Höhe und Breite in Pixeln auswählen
- Ordnerdialoge für Quell- und Zielordner wählen
- Alle Bilder, die die Mindestauflösung haben oder überschreiten, werden in den gewählten Zielordner verschoben
Fehler sind in ./error_log.txt
Add-Type -AssemblyName System.Drawing
Add-Type -AssemblyName System.Windows.Forms
# Get the directory of the script
$scriptPath = Split-Path -Parent $MyInvocation.MyCommand.Path
$logFile = Join-Path $scriptPath "error_log.txt"
# Function to log errors
function Log-Error {
param (
[string]$message
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
"$timestamp - $message" | Out-File -FilePath $logFile -Append
}
# Function to show folder selection dialog
function Select-Folder {
param (
[string]$Description
)
$folderBrowser = New-Object System.Windows.Forms.FolderBrowserDialog
$folderBrowser.Description = $Description
$folderBrowser.RootFolder = [System.Environment+SpecialFolder]::MyComputer
if ($folderBrowser.ShowDialog() -eq "OK") {
return $folderBrowser.SelectedPath
}
return $null
}
# Prompt user for resolution
do {
$targetWidth = Read-Host "Enter the target width in pixels (e.g., 3840 for 4K)"
} while (-not ($targetWidth -match '^\d+$'))
do {
$targetHeight = Read-Host "Enter the target height in pixels (e.g., 2160 for 4K)"
} while (-not ($targetHeight -match '^\d+$'))
$targetWidth = [int]$targetWidth
$targetHeight = [int]$targetHeight
Write-Host "Target resolution: $targetWidth x $targetHeight"
# Prompt user to select source and destination folders
$sourceFolder = Select-Folder "Select the source folder containing images"
if (-not $sourceFolder) {
Write-Host "Source folder selection cancelled. Exiting script."
exit
}
$destinationFolder = Select-Folder "Select the destination folder for matching images"
if (-not $destinationFolder) {
Write-Host "Destination folder selection cancelled. Exiting script."
exit
}
# Create destination folder if it doesn't exist
if (!(Test-Path -Path $destinationFolder)) {
New-Item -ItemType Directory -Path $destinationFolder | Out-Null
Write-Host "Created destination folder: $destinationFolder"
}
# Get all image files in the source folder
$imageFiles = Get-ChildItem -Path $sourceFolder -Include *.jpg, *.jpeg, *.png, *.bmp -File -Recurse
if ($imageFiles.Count -eq 0) {
$message = "No image files found in $sourceFolder"
Write-Host $message
Log-Error $message
exit
}
Write-Host "Found $($imageFiles.Count) image files to process"
# Initialize counter and total
$i = 0
$total = $imageFiles.Count
$movedCount = 0
# Initialize progress bar
Write-Progress -Activity "Processing Images" -Status "0% Complete" -PercentComplete 0
foreach ($file in $imageFiles) {
try {
$image = $null
try {
$image = [System.Drawing.Image]::FromFile($file.FullName)
$width = $image.Width
$height = $image.Height
# Check if image meets or exceeds target resolution
if ($width -ge $targetWidth -and $height -ge $targetHeight) {
# Close the image before moving
$image.Dispose()
$image = $null
# Move the file to the destination folder
Move-Item -Path $file.FullName -Destination $destinationFolder -Force
Write-Host "Moved: $($file.Name) (${width}x${height})"
$movedCount++
}
}
finally {
# Ensure image is disposed even if an error occurs
if ($image -ne $null) {
$image.Dispose()
}
}
}
catch {
$errorMessage = "Error processing $($file.Name): $_"
Write-Host $errorMessage
Log-Error $errorMessage
}
# Update progress
$i++
$percentComplete = ($i / $total) * 100
Write-Progress -Activity "Processing Images" -Status "$i of $total processed" -PercentComplete $percentComplete
}
Write-Progress -Activity "Processing Images" -Completed
Write-Host "Processing complete. Moved $movedCount out of $total images."
ungetestete BETA
Mit Claude Sonnet erweitert. Hinzu kommen Abfragen nach Ordnern und Auflösung, Erkennung der Bildschirmauflösung etc.
ungetesteter direkter AI output
Add-Type -AssemblyName System.Drawing
Add-Type -AssemblyName System.Windows.Forms
# Get the directory of the script
$scriptPath = Split-Path -Parent $MyInvocation.MyCommand.Path
$logFile = Join-Path $scriptPath "error_log.txt"
# Function to log errors
function Log-Error {
param (
[string]$message
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
"$timestamp - $message" | Out-File -FilePath $logFile -Append
}
# Function to show folder selection dialog
function Select-Folder {
param (
[string]$Description
)
$folderBrowser = New-Object System.Windows.Forms.FolderBrowserDialog
$folderBrowser.Description = $Description
$folderBrowser.RootFolder = [System.Environment+SpecialFolder]::MyComputer
if ($folderBrowser.ShowDialog() -eq "OK") {
return $folderBrowser.SelectedPath
}
return $null
}
# Get current screen resolution
$currentResolution = (Get-WmiObject -Class Win32_VideoController).VideoModeDescription
$resolutionMatch = $currentResolution -match '(\d+)\s*x\s*(\d+)'
if ($resolutionMatch) {
$currentWidth = [int]$Matches[1]
$currentHeight = [int]$Matches[2]
Write-Host "Current screen resolution: $currentWidth x $currentHeight"
$useCurrentResolution = Read-Host "Do you want to use the current screen resolution? (Y/N)"
if ($useCurrentResolution -eq 'Y' -or $useCurrentResolution -eq 'y') {
$targetWidth = $currentWidth
$targetHeight = $currentHeight
}
}
# If not using current resolution, prompt user for resolution
if (-not $targetWidth -or -not $targetHeight) {
do {
$targetWidth = Read-Host "Enter the target width in pixels (e.g., 3840 for 4K)"
} while (-not ($targetWidth -match '^\d+$'))
do {
$targetHeight = Read-Host "Enter the target height in pixels (e.g., 2160 for 4K)"
} while (-not ($targetHeight -match '^\d+$'))
$targetWidth = [int]$targetWidth
$targetHeight = [int]$targetHeight
}
Write-Host "Target resolution: $targetWidth x $targetHeight"
# Prompt user to select source and destination folders
$sourceFolder = Select-Folder "Select the source folder containing images"
if (-not $sourceFolder) {
Write-Host "Source folder selection cancelled. Exiting script."
exit
}
$destinationFolder = Select-Folder "Select the destination folder for matching images"
if (-not $destinationFolder) {
Write-Host "Destination folder selection cancelled. Exiting script."
exit
}
# Create destination folder if it doesn't exist
if (!(Test-Path -Path $destinationFolder)) {
New-Item -ItemType Directory -Path $destinationFolder | Out-Null
Write-Host "Created destination folder: $destinationFolder"
}
# Get all image files in the source folder
$imageFiles = Get-ChildItem -Path $sourceFolder -Include *.jpg, *.jpeg, *.png, *.bmp -File -Recurse
if ($imageFiles.Count -eq 0) {
$message = "No image files found in $sourceFolder"
Write-Host $message
Log-Error $message
exit
}
Write-Host "Found $($imageFiles.Count) image files to process"
# Initialize counter and total
$i = 0
$total = $imageFiles.Count
$movedCount = 0
# Initialize progress bar
Write-Progress -Activity "Processing Images" -Status "0% Complete" -PercentComplete 0
foreach ($file in $imageFiles) {
try {
$image = $null
try {
$image = [System.Drawing.Image]::FromFile($file.FullName)
$width = $image.Width
$height = $image.Height
# Check if image meets or exceeds target resolution
if ($width -ge $targetWidth -and $height -ge $targetHeight) {
# Close the image before moving
$image.Dispose()
$image = $null
# Move the file to the destination folder
Move-Item -Path $file.FullName -Destination $destinationFolder -Force
Write-Host "Moved: $($file.Name) (${width}x${height})"
$movedCount++
}
}
finally {
# Ensure image is disposed even if an error occurs
if ($image -ne $null) {
$image.Dispose()
}
}
}
catch {
$errorMessage = "Error processing $($file.Name): $_"
Write-Host $errorMessage
Log-Error $errorMessage
}
# Update progress
$i++
$percentComplete = ($i / $total) * 100
Write-Progress -Activity "Processing Images" -Status "$i of $total processed" -PercentComplete $percentComplete
}
Write-Progress -Activity "Processing Images" -Completed
Write-Host "Processing complete. Moved $movedCount out of $total images."
Bilder <4K verschieben
PYTHON, kein Powershell
pip install Pillow tqdm
import os
from PIL import Image
import shutil
from pathlib import Path
from concurrent.futures import ThreadPoolExecutor
from tqdm import tqdm
# Import and disable the DecompressionBombWarning
from PIL import Image, ImageFile
Image.MAX_IMAGE_PIXELS = None # Disable the warning
ImageFile.LOAD_TRUNCATED_IMAGES = True # Handle truncated images
def get_image_resolution(image_path):
"""Get the resolution of an image file."""
try:
with Image.open(image_path) as img:
return img.size
except Exception as e:
print(f"Error reading {image_path}: {str(e)}")
return None
def is_4k_or_higher(width, height):
"""Check if the resolution is 4K (3840x2160) or higher."""
return width >= 3840 and height >= 2160
def process_image(image_path, destination_folder):
"""Process a single image and move it if not 4K."""
try:
resolution = get_image_resolution(image_path)
if resolution is None:
return
width, height = resolution
if not is_4k_or_higher(width, height):
# Create destination folder if it doesn't exist
Path(destination_folder).mkdir(parents=True, exist_ok=True)
# Get destination path
dest_path = os.path.join(destination_folder, os.path.basename(image_path))
# Move file, overwriting if it exists
shutil.move(image_path, dest_path)
except Exception as e:
print(f"Error processing {image_path}: {str(e)}")
def main():
# Configuration
source_folder = input("Enter the source folder path: ")
destination_folder = input("Enter the destination folder for non-4K images: ")
# Validate source folder
if not os.path.exists(source_folder):
print("Source folder does not exist!")
return
# Get list of image files
image_files = [
os.path.join(source_folder, f)
for f in os.listdir(source_folder)
if f.lower().endswith(('.png', '.jpg', '.jpeg'))
]
if not image_files:
print("No image files found in the source folder!")
return
print(f"Found {len(image_files)} images. Processing...")
# Process images using thread pool for better performance
with ThreadPoolExecutor(max_workers=8) as executor:
list(tqdm(
executor.map(
lambda x: process_image(x, destination_folder),
image_files
),
total=len(image_files),
desc="Processing images"
))
print("Done! All non-4K images have been moved.")
if __name__ == "__main__":
main()
Bilder >= 4K verschieben
PYTHON
pip install Pillow tqdm
import os
from PIL import Image
import shutil
from pathlib import Path
from concurrent.futures import ThreadPoolExecutor
from tqdm import tqdm
import warnings
import logging
import sys
from datetime import datetime
# Import and disable the DecompressionBombWarning
from PIL import Image, ImageFile
Image.MAX_IMAGE_PIXELS = None # Disable the warning
ImageFile.LOAD_TRUNCATED_IMAGES = True # Handle truncated images
# Get the script's filename without extension to create log filename
script_path = sys.argv[0]
script_name = os.path.splitext(os.path.basename(script_path))[0]
log_filename = f"{script_name}_errors.log"
# Setup logging
logging.basicConfig(
filename=log_filename,
level=logging.WARNING,
format='%(asctime)s - %(message)s',
datefmt='%Y-%m-%d %H:%M:%S'
)
# Custom warning handler to redirect warnings to logging
def handle_warning(message, category, filename, lineno, file=None, line=None):
logging.warning(f"Warning: {message}")
# Replace the default warning handler
warnings.showwarning = handle_warning
def get_image_resolution(image_path):
"""Get the resolution of an image file."""
try:
with Image.open(image_path) as img:
return img.size
except Exception as e:
logging.error(f"Error reading image {image_path}: {str(e)}")
return None
def is_4k_or_higher(width, height):
"""Check if the resolution is 4K (3840x2160) or higher."""
return width >= 3840 and height >= 2160
def process_image(image_path, destination_folder):
"""Process a single image and move it if it IS 4K or higher."""
try:
resolution = get_image_resolution(image_path)
if resolution is None:
return
width, height = resolution
if is_4k_or_higher(width, height):
# Create destination folder if it doesn't exist
Path(destination_folder).mkdir(parents=True, exist_ok=True)
# Get destination path
dest_path = os.path.join(destination_folder, os.path.basename(image_path))
# Move file, overwriting if it exists
shutil.move(image_path, dest_path)
except Exception as e:
logging.error(f"Error processing {image_path}: {str(e)}")
def main():
# Log script start
logging.info(f"Script started at {datetime.now()}")
# Configuration
source_folder = input("Enter the source folder path: ")
destination_folder = input("Enter the destination folder for 4K and higher resolution images: ")
# Log folders
logging.info(f"Source folder: {source_folder}")
logging.info(f"Destination folder: {destination_folder}")
# Validate source folder
if not os.path.exists(source_folder):
logging.error("Source folder does not exist!")
print("Source folder does not exist!")
return
# Get list of image files
image_files = [
os.path.join(source_folder, f)
for f in os.listdir(source_folder)
if f.lower().endswith(('.png', '.jpg', '.jpeg'))
]
if not image_files:
logging.warning("No image files found in the source folder!")
print("No image files found in the source folder!")
return
print(f"Found {len(image_files)} images. Processing...")
logging.info(f"Found {len(image_files)} images to process")
# Process images using thread pool for better performance
with ThreadPoolExecutor(max_workers=8) as executor:
list(tqdm(
executor.map(
lambda x: process_image(x, destination_folder),
image_files
),
total=len(image_files),
desc="Processing images"
))
logging.info(f"Script completed at {datetime.now()}")
print("Done! All 4K and higher resolution images have been moved.")
print(f"Check {log_filename} for any errors that occurred during processing.")
if __name__ == "__main__":
main()
Upscaling
Lanczos auf 4K (min eine Seitenlänge)
pip install Pillow tqdm
from PIL import Image
import os
from pathlib import Path
import sys
from tqdm import tqdm
def upscale_to_4k(image_path, output_path):
"""
Upscale an image to 4K resolution (3840×2160) while maintaining aspect ratio.
At least one dimension will match 4K resolution.
"""
try:
# Open the image
with Image.open(image_path) as img:
# Get original dimensions
width, height = img.size
# Calculate aspect ratio
aspect_ratio = width / height
# Calculate new dimensions
if aspect_ratio > 16/9: # Wider than 4K aspect ratio
new_height = 2160
new_width = int(new_height * aspect_ratio)
else: # Taller than 4K aspect ratio
new_width = 3840
new_height = int(new_width / aspect_ratio)
# Upscale image using Lanczos resampling
upscaled_img = img.resize((new_width, new_height), Image.Resampling.LANCZOS)
# Create output directory if it doesn't exist
os.makedirs(os.path.dirname(output_path), exist_ok=True)
# Save the upscaled image with original format
upscaled_img.save(output_path, quality=95)
return True
except Exception as e:
print(f"Error processing {image_path}: {str(e)}")
return False
def get_yes_no_input(prompt):
"""Helper function to get valid yes/no input from user"""
while True:
response = input(prompt).strip().lower()
if response in ['y', 'yes']:
return True
elif response in ['n', 'no']:
return False
print("Please enter 'y' or 'n'")
def get_image_files(input_dir, include_subfolders):
"""Get list of image files to process"""
supported_formats = {'.jpg', '.jpeg', '.png', '.bmp', '.tiff'}
if include_subfolders:
file_iterator = Path(input_dir).rglob('*')
else:
file_iterator = Path(input_dir).glob('*')
return [f for f in file_iterator if f.suffix.lower() in supported_formats]
def process_directory(input_dir, output_dir, include_subfolders):
"""Process images in the directory based on subfolder preference"""
processed = 0
failed = 0
# Get list of files first
image_files = get_image_files(input_dir, include_subfolders)
total_files = len(image_files)
if total_files == 0:
print("No supported image files found!")
return 0, 0
# Create progress bar
with tqdm(total=total_files, desc="Progress", unit="image", position=1, leave=True) as pbar:
for file_path in image_files:
# Move cursor up one line to print file info above progress bar
print(f"\033[A\033[K\nProcessing: {file_path.name}")
# Create corresponding output path
relative_path = file_path.relative_to(input_dir)
output_path = Path(output_dir) / relative_path
if upscale_to_4k(str(file_path), str(output_path)):
processed += 1
print(f"\033[A\033[KSuccessfully upscaled: {file_path.name}")
else:
failed += 1
# Update progress bar
pbar.update(1)
# Move cursor back down to progress bar
print("\033[B", end="")
return processed, failed
def main():
# Clear screen for better visibility
print("\033[2J\033[H")
# Get input and output directories from user
input_dir = input("Enter the path to the folder containing images: ").strip()
output_dir = input("Enter the path where upscaled images should be saved: ").strip()
# Ask about subfolder inclusion
include_subfolders = get_yes_no_input("Do you want to include subfolders? (y/n): ")
# Validate input directory
if not os.path.exists(input_dir):
print("Error: Input directory does not exist!")
sys.exit(1)
# Create output directory if it doesn't exist
os.makedirs(output_dir, exist_ok=True)
print("\nStarting image upscaling process...")
if include_subfolders:
print("Processing main folder and all subfolders...")
else:
print("Processing main folder only...")
# Add an empty line for the progress information
print("")
# Process the directory
processed, failed = process_directory(input_dir, output_dir, include_subfolders)
# Print summary
print(f"\nUpscaling complete!")
print(f"Successfully processed: {processed} images")
print(f"Failed: {failed} images")
if __name__ == "__main__":
main()
KI-Tools
Computerbilder von Photos trennen
Das hier ist noch nicht ausreichend getestetgetestet.
Das verwendete Modell resnet50 muss auf euren Bilddatensatz trainiert werden oder ihr müsst persönlich mit euren color_variance Werten spielen
pip install pillow torch torchvision
import torch
import torchvision.transforms as transforms
import torchvision.models as models
from PIL import Image
import os
import shutil
from torch import nn
import numpy as np
from pathlib import Path
import tkinter as tk
from tkinter import filedialog
class ImageSorter:
def __init__(self):
# Load pretrained ResNet model
self.model = models.resnet50(pretrained=True)
num_features = self.model.fc.in_features
self.model.fc = nn.Linear(num_features, 2) # 0: photo, 1: digital art
self.transform = transforms.Compose([
transforms.Resize((224, 224)),
transforms.ToTensor(),
transforms.Normalize(
mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225]
)
])
self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
self.model = self.model.to(self.device)
def analyze_image_features(self, image_path):
"""
Analyze various features of the image to determine if it's digital art
"""
try:
image = Image.open(image_path).convert('RGB')
# Convert to numpy array for analysis
img_array = np.array(image)
# Feature 1: Check color distribution
color_variance = np.var(img_array, axis=(0,1)).mean()
# Feature 2: Check for perfect edges
edges = np.diff(img_array)
edge_score = np.abs(edges).mean()
# Feature 3: Check color patterns
unique_colors = len(np.unique(img_array.reshape(-1, 3), axis=0))
color_ratio = unique_colors / (img_array.shape[0] * img_array.shape[1])
# Create feature vector
features = {
'color_variance': color_variance,
'edge_score': edge_score,
'color_ratio': color_ratio
}
return features
except Exception as e:
print(f"Error analyzing {image_path}: {str(e)}")
return None
def is_digital_art(self, image_path, threshold=0.7):
"""
Determine if an image is digital art based on multiple criteria
"""
features = self.analyze_image_features(image_path)
if not features:
return False
# Define typical characteristics of digital art
is_digital = (
features['color_variance'] < 1000 and # Lower color variance
features['edge_score'] < 20 and # Smoother edges
features['color_ratio'] < 0.1 # Fewer unique colors relative to size
)
return is_digital
def sort_images(self, input_directory):
"""
Sort images into 'photos' and 'digital_art' subdirectories
"""
# Convert input path to Path object and resolve any special characters
input_path = Path(input_directory).resolve()
# Create output directories using Path
digital_art_dir = input_path / 'digital_art'
photos_dir = input_path / 'photos'
digital_art_dir.mkdir(exist_ok=True, parents=True)
photos_dir.mkdir(exist_ok=True, parents=True)
print(f"\nCreated directories:")
print(f"Digital Art: {digital_art_dir}")
print(f"Photos: {photos_dir}\n")
# Supported image formats
supported_formats = {'.jpg', '.jpeg', '.png', '.bmp'}
# Process each image
files_processed = 0
total_files = len([f for f in input_path.iterdir() if f.is_file() and f.suffix.lower() in supported_formats])
for file_path in input_path.iterdir():
if file_path.is_file() and file_path.suffix.lower() in supported_formats:
# Skip if it's already in a subdirectory
if 'digital_art' in str(file_path) or 'photos' in str(file_path):
continue
try:
files_processed += 1
print(f"Processing image {files_processed}/{total_files}: {file_path.name}")
if self.is_digital_art(str(file_path)):
destination = digital_art_dir / file_path.name
print(f"→ Moving to digital_art folder")
else:
destination = photos_dir / file_path.name
print(f"→ Moving to photos folder")
shutil.move(str(file_path), str(destination))
except Exception as e:
print(f"Error processing {file_path.name}: {str(e)}")
print(f"\nProcessing complete!")
print(f"Total images processed: {files_processed}")
def get_folder_path():
"""
Show folder selection dialog and return the selected path
"""
# Hide the main tkinter window
root = tk.Tk()
root.withdraw()
# Show folder selection dialog
folder_path = filedialog.askdirectory(
title='Select folder containing images to sort'
)
return folder_path if folder_path else None
def main():
print("Digital Art Sorter")
print("=================")
# Get folder path from user
folder_path = get_folder_path()
if not folder_path:
print("No folder selected. Exiting...")
return
print(f"\nSelected folder: {folder_path}")
# Confirm with user
confirmation = input("\nPress Enter to start sorting images, or 'q' to quit: ")
if confirmation.lower() == 'q':
print("Operation cancelled.")
return
sorter = ImageSorter()
sorter.sort_images(folder_path)
print("\nDone! Press Enter to exit...")
input()
if __name__ == "__main__":
main()
Dedup
macht man am besten mit Czkawka oder DupeGuru
Basic Dedup
ChatGPT 3.5
(falls Copy statt Move im Script vorab gemacht wurde)
Das Ding tut noch nicht das was ich will, womöglich komme ich selbst durcheinander mit Source und Destination. Ich setz also unten noch mal anders an.
param (
# Mag etwas durcheinander und verkehrt sein. KI halt... Jedenfalls ist Destination der Ordner der über bleiben soll. und source der Ordner in dem die Duplikate liegen
# Ordner in dem gelöscht wird.
[string]$SourceFolder = "XXXXXXXXXXXXXXXXXXXXXXXXX",
# Ordner gegen den Verglichen wird
[string]$DestinationFolder = "XXXXXXXXXXXXXXXXXXXX",
)
# Get all image files in the destination folder
$destinationImages = Get-ChildItem -Path $DestinationFolder -Filter "*.jpg" -File
# Initialize counters for deleted images in each folder
$deletedInSourceFolderCount = 0
$deletedInDestinationFolderCount = 0
# Process each image file in the destination folder
foreach ($destinationImage in $destinationImages) {
Write-Host "Processing $($destinationImage.FullName)"
# Construct the source file path based on the destination file name
$sourceFilePath = Join-Path -Path $SourceFolder -ChildPath $destinationImage.Name
# Check if the corresponding file exists in the source folder
if (Test-Path $sourceFilePath) {
Write-Host "Deleting $($sourceFilePath)"
# Remove the item (move to Recycle Bin)
Remove-Item -Path $sourceFilePath -Force -Confirm:$false
# Increment the counter for deleted images in the source folder
$deletedInSourceFolderCount++
}
# Increment the counter for deleted images in the destination folder
$deletedInDestinationFolderCount++
}
# Output the deletion statistics
Write-Host "Duplicate removal complete!"
Write-Host "Deleted $deletedInSourceFolderCount images in the source folder: $SourceFolder"
Prüfscripts
Prüfen ob keine Bilder >4K existieren
ChatGPT 3.5
$SourceFolder = "C:\Path\to\SourceFolder"
$MinWidth = 3840
$MinHeight = 2160
# Get all image files in the source folder and its subfolders
$images = Get-ChildItem -Path $SourceFolder -Filter "*.jpg" -File -Recurse
$totalImages = $images.Count
$processedImages = 0
# Process each image file
foreach ($image in $images) {
# Use .NET classes to read image dimensions
$imageStream = New-Object System.IO.FileStream($image.FullName, [System.IO.FileMode]::Open)
$imageBitmap = New-Object System.Drawing.Bitmap($imageStream)
$width = $imageBitmap.Width
$height = $imageBitmap.Height
$imageStream.Close()
# Check if the image is larger than the specified dimensions
if ($width -ge $MinWidth -and $height -ge $MinHeight) {
Write-Host "Found large image: $($image.FullName)"
}
$processedImages++
$progress = [math]::Round(($processedImages / $totalImages) * 100, 2)
Write-Progress -Activity "Checking image sizes" -Status "Progress: $progress%" -PercentComplete $progress
}
Write-Progress -Activity "Checking image sizes" -Status "Progress: 100%" -PercentComplete 100
Write-Host "Image size check complete!"
Alle Bilder > 4K löschen
$SourceFolder = "C:\Path\to\SourceFolder"
$MinWidth = 3840
$MinHeight = 2160
# Get all image files in the source folder and its subfolders
$images = Get-ChildItem -Path $SourceFolder -Filter "*.jpg" -File -Recurse
$totalImages = $images.Count
$processedImages = 0
# Process each image file
foreach ($image in $images) {
# Use .NET classes to read image dimensions
$imageStream = New-Object System.IO.FileStream($image.FullName, [System.IO.FileMode]::Open)
$imageBitmap = New-Object System.Drawing.Bitmap($imageStream)
$width = $imageBitmap.Width
$height = $imageBitmap.Height
$imageStream.Close()
# Check if the image is larger than the specified dimensions
if ($width -ge $MinWidth -and $height -ge $MinHeight) {
Write-Host "Deleting large image: $($image.FullName)"
Remove-Item -Path $image.FullName -Force
}
$processedImages++
$progress = [math]::Round(($processedImages / $totalImages) * 100, 2)
Write-Progress -Activity "Checking and deleting large images" -Status "Progress: $progress%" -PercentComplete $progress
}
Write-Progress -Activity "Checking and deleting large images" -Status "Progress: 100%" -PercentComplete 100
Write-Host "Image size check and deletion complete!"