Bulk File Rename/ Image Resize
Application
Image Processing:
Image processing involves transforming or analyzing digital images to extract useful
information or enhance their quality. Common operations include:
• Resizing: Changing the dimensions of an image.
• Filtering: Removing noise or enhancing features.
• Transformations: Rotating, flipping, cropping, etc.
• Compression: Reducing file size.
🛠 Libraries Used:
• PIL (Pillow): For loading, resizing, and saving images.
• OpenCV: A powerful library for real-time image and video processing (though
not actively used in your functions).
• Matplotlib: To visualize image comparisons.
• NumPy: Backbone for numerical operations on image arrays.
UI with ipywidgets:
ipywidgets are interactive HTML widgets for Jupyter notebooks that allow users to
manipulate code and data visually.
Your app uses widgets like:
• FileUpload: To upload images.
• IntText, Text: For user input.
• Button: For triggering actions.
• Output: For dynamically displaying results.
Using os:
• Read directory contents.
• Rename files.
• Create and delete temporary folders.
Good for:
• Batch processing
• Organizing outputs
5. Data Visualization with Pandas & Matplotlib:
After operations, you visualize:
• Renaming processes using a DataFrame.
• Operation statistics using:
• Pie charts (operation distribution)
• Line charts (timestamped activity trends)
These enhance data interpretation and usability.
CODE:
import os
from PIL import Image
import cv2
import numpy as np
from datetime import datetime
from google.colab import files
from IPython.display import display, HTML, clear_output
import ipywidgets as widgets
from io import BytesIO
import base64
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
class ImageProcessor:
def __init__(self):
self.history = []
def resize_image(self, image_path, width, height, output_path):
try:
img = Image.open(image_path)
resized_img = img.resize((width, height), Image.Resampling.LANCZOS)
resized_img.save(output_path)
self.history.append({
'operation': 'resize',
'original': image_path,
'new': output_path,
'dimensions': (width, height),
'timestamp': datetime.now()
})
return True
except Exception as e:
print(f"Error resizing image: {e}")
return False
def rename_files(self, directory, prefix, start_number):
try:
files = [f for f in os.listdir(directory) if os.path.isfile(os.path.join(directory, f))]
counter = start_number
for file in files:
extension = os.path.splitext(file)[1]
new_name = f"{prefix}_{counter}{extension}"
old_path = os.path.join(directory, file)
new_path = os.path.join(directory, new_name)
os.rename(old_path, new_path)
self.history.append({
'operation': 'rename',
'original': old_path,
'new': new_path,
'timestamp': datetime.now()
})
counter += 1
return True
except Exception as e:
print(f"Error renaming files: {e}")
return False
class ColabImageProcessor:
def __init__(self):
self.processor = ImageProcessor()
self.setup_ui()
def setup_ui(self):
# Create widgets
self.upload_button = widgets.FileUpload(
accept='image/*',
multiple=False,
description='Upload Image'
)
self.width_input = widgets.IntText(
value=800,
description='Width:',
disabled=False
)
self.height_input = widgets.IntText(
value=600,
description='Height:',
disabled=False
)
self.resize_button = widgets.Button(
description='Resize Image',
disabled=False,
button_style='',
tooltip='Click to resize image'
)
self.rename_prefix = widgets.Text(
value='',
placeholder='Enter prefix',
description='Prefix:',
disabled=False
)
self.start_number = widgets.IntText(
value=1,
description='Start Number:',
disabled=False
)
self.rename_button = widgets.Button(
description='Rename Files',
disabled=False,
button_style='',
tooltip='Click to rename files'
)
self.history_button = widgets.Button(
description='Show History',
disabled=False,
button_style='',
tooltip='Click to view operation history'
)
self.output = widgets.Output()
# Set up event handlers
self.resize_button.on_click(self.on_resize_click)
self.rename_button.on_click(self.on_rename_click)
self.history_button.on_click(self.show_history)
self.upload_button.observe(self.preview_image, names='value')
# Create layout
resize_box = widgets.VBox([
widgets.HTML('<h2>Image Resize</h2>'),
self.upload_button,
self.width_input,
self.height_input,
self.resize_button
])
rename_box = widgets.VBox([
widgets.HTML('<h2>Bulk Rename</h2>'),
self.rename_prefix,
self.start_number,
self.rename_button
])
history_box = widgets.VBox([
widgets.HTML('<h2>History</h2>'),
self.history_button
])
# Display the UI
display(widgets.VBox([resize_box, rename_box, history_box, self.output]))
def preview_image(self, change):
with self.output:
clear_output()
if not self.upload_button.value:
return
# Get the uploaded file
uploaded_file = list(self.upload_button.value.values())[0]
content = uploaded_file['content']
# Create a temporary file
temp_input = 'temp_input.jpg'
with open(temp_input, 'wb') as f:
f.write(content)
# Display original image
display(HTML('<h3>Original Image Preview:</h3>'))
img = Image.open(temp_input)
display(img)
# Show image details
display(HTML(f'''
<h4>Image Details:</h4>
<ul>
<li>Size: {img.size}</li>
<li>Mode: {img.mode}</li>
<li>Format: {img.format}</li>
</ul>
'''))
# Clean up
os.remove(temp_input)
def on_resize_click(self, b):
with self.output:
clear_output()
if not self.upload_button.value:
print("Please upload an image first!")
return
# Get the uploaded file
uploaded_file = list(self.upload_button.value.values())[0]
content = uploaded_file['content']
# Create temporary files
temp_input = 'temp_input.jpg'
temp_output = 'temp_output.jpg'
with open(temp_input, 'wb') as f:
f.write(content)
# Resize the image
success = self.processor.resize_image(
temp_input,
self.width_input.value,
self.height_input.value,
temp_output
)
if success:
# Display before and after comparison
display(HTML('<h3>Before and After Comparison:</h3>'))
# Create figure with two subplots
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(15, 5))
# Original image
original_img = Image.open(temp_input)
ax1.imshow(original_img)
ax1.set_title('Original Image')
ax1.axis('off')
# Resized image
resized_img = Image.open(temp_output)
ax2.imshow(resized_img)
ax2.set_title('Resized Image')
ax2.axis('off')
plt.tight_layout()
plt.show()
# Display image details
display(HTML(f'''
<h4>Image Details:</h4>
<ul>
<li>Original Size: {original_img.size}</li>
<li>Resized Size: {resized_img.size}</li>
<li>Scale Factor: {self.width_input.value/original_img.size[0]:.2f}x</li>
</ul>
'''))
# Offer download
print("Click the link below to download the resized image:")
files.download(temp_output)
# Clean up
os.remove(temp_input)
os.remove(temp_output)
else:
print("Failed to resize image!")
def on_rename_click(self, b):
with self.output:
clear_output()
if not self.rename_prefix.value:
print("Please enter a prefix!")
return
# Create a temporary directory for testing
temp_dir = 'temp_rename'
os.makedirs(temp_dir, exist_ok=True)
# Create some test files
for i in range(3):
with open(os.path.join(temp_dir, f'test_{i}.txt'), 'w') as f:
f.write(f'Test file {i}')
# Rename files
success = self.processor.rename_files(
temp_dir,
self.rename_prefix.value,
self.start_number.value
)
if success:
# Create a visualization of the renaming process
display(HTML('<h3>Renaming Process Visualization:</h3>'))
# Get the files before and after renaming
original_files = [f'test_{i}.txt' for i in range(3)]
renamed_files = sorted(os.listdir(temp_dir))
# Create a comparison table
df = pd.DataFrame({
'Original Name': original_files,
'New Name': renamed_files
})
# Display the table
display(df)
# Create a bar chart showing the number of files renamed
plt.figure(figsize=(10, 4))
plt.bar(['Original', 'Renamed'], [len(original_files), len(renamed_files)])
plt.title('Number of Files Before and After Renaming')
plt.ylabel('Count')
plt.show()
else:
print("Failed to rename files!")
# Clean up
for file in os.listdir(temp_dir):
os.remove(os.path.join(temp_dir, file))
os.rmdir(temp_dir)
def show_history(self, b):
with self.output:
clear_output()
if not self.processor.history:
print("No history available yet!")
return
# Convert history to DataFrame
df = pd.DataFrame(self.processor.history)
# Display history table
display(HTML('<h3>Operation History:</h3>'))
display(df)
# Create visualizations
plt.figure(figsize=(12, 6))
# Plot 1: Operation types
plt.subplot(1, 2, 1)
df['operation'].value_counts().plot(kind='pie', autopct='%1.1f%%')
plt.title('Operation Types Distribution')
# Plot 2: Timeline of operations
plt.subplot(1, 2, 2)
df['timestamp'] = pd.to_datetime(df['timestamp'])
df.set_index('timestamp').resample('1min').count()['operation'].plot()
plt.title('Operations Over Time')
plt.xlabel('Time')
plt.ylabel('Number of Operations')
plt.tight_layout()
plt.show()
# Create and run the application
if __name__ == "__main__":
app = ColabImageProcessor()
OUTPUT:
Before and After Comparison:
Image Details:
• Original Size: (500, 281)
• Resized Size: (200, 500)
• Scale Factor: 0.40x
Click the link below to download the resized image:
Downloading "temp_output.jpg":