Multithreading

This commit is contained in:
sherlock 2025-04-16 20:24:15 +05:30
parent 90e5bd61ed
commit 7daef19461
2 changed files with 12 additions and 16 deletions

22
jpeg.py
View file

@ -6,9 +6,9 @@ from functools import partial
import time import time
def generate_certificate(template_path, font_path, name, output_path, index, font_size=50, text_color="black", y_offset=0): def generate_certificate(template_path, font_path, name, output_path, index, font_size=50, text_color="black", y_offset=0):
# Open the certificate template image
with Image.open(template_path) as image: with Image.open(template_path) as image:
# For JPG compatibility, convert to RGB instead of RGBA
# Colorspace and Drawable Area
image = image.convert("RGB") image = image.convert("RGB")
draw = ImageDraw.Draw(image) draw = ImageDraw.Draw(image)
@ -18,19 +18,17 @@ def generate_certificate(template_path, font_path, name, output_path, index, fon
# Image dimensions # Image dimensions
image_width, image_height = image.size image_width, image_height = image.size
# Calculate the bounding box for the text # bounding box for text
bbox = draw.textbbox((0, 0), name, font=font) bbox = draw.textbbox((0, 0), name, font=font)
text_width = bbox[2] - bbox[0] text_width = bbox[2] - bbox[0]
text_height = bbox[3] - bbox[1] text_height = bbox[3] - bbox[1]
# Calculate coordinates for centered text # coordinates for centered text
x = (image_width - text_width) / 2 x = (image_width - text_width) / 2
y = (image_height - text_height) / 2 + y_offset y = (image_height - text_height) / 2 + y_offset
# Draw the text onto the certificate image
draw.text((x, y), name, fill=text_color, font=font) draw.text((x, y), name, fill=text_color, font=font)
# Save the image as JPG
output_filename = os.path.join(output_path, f"certificate_{index:03d}.jpg") output_filename = os.path.join(output_path, f"certificate_{index:03d}.jpg")
image.save(output_filename, quality=95) # Set JPG quality image.save(output_filename, quality=95) # Set JPG quality
print(f"Saved certificate for {name} as {output_filename}") print(f"Saved certificate for {name} as {output_filename}")
@ -41,7 +39,7 @@ def process_certificate(row, i, template_path, font_path, output_folder, font_si
def main(): def main():
start_time = time.time() start_time = time.time()
template_path = "cert.jpg" # Certificate template image filename (JPG format) template_path = "cert.jpg" # Certificate template image filename (JPG format)
font_path = "CrimsonText-Bold.ttf" # Path to the font file (TTF or OTF) font_path = "CrimsonText-Bold.ttf" # Path to the font file (TTF or OTF)
csv_file = "participants.csv" # CSV file containing the name list csv_file = "participants.csv" # CSV file containing the name list
output_folder = "certificates" # Output folder for generated certificates output_folder = "certificates" # Output folder for generated certificates
@ -49,19 +47,19 @@ def main():
text_color = "black" text_color = "black"
y_offset = -82 y_offset = -82
# Optimal number of workers # number of workers - for multithreading
cpu_count = os.cpu_count() cpu_count = os.cpu_count()
max_workers = min(32, (cpu_count + 4) if cpu_count is not None else 4) max_workers = min(32, (cpu_count + 4) if cpu_count is not None else 4)
if not os.path.exists(output_folder): if not os.path.exists(output_folder):
os.makedirs(output_folder) os.makedirs(output_folder)
# Read all data from CSV at once # concurrent reading from CSV
with open(csv_file, newline='', encoding='utf-8') as csvfile: with open(csv_file, newline='', encoding='utf-8') as csvfile:
reader = csv.DictReader(csvfile) reader = csv.DictReader(csvfile)
participants = list(reader) participants = list(reader)
# Create a partial function with all the fixed parameters # partial function with all the fixed parameters
process_func = partial( process_func = partial(
process_certificate, process_certificate,
template_path=template_path, template_path=template_path,
@ -74,10 +72,10 @@ def main():
# Process certificates in parallel # Process certificates in parallel
with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor: with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor:
# Submit all tasks # task submission
futures = [executor.submit(process_func, row, i) for i, row in enumerate(participants, start=1)] futures = [executor.submit(process_func, row, i) for i, row in enumerate(participants, start=1)]
# Wait for all to complete # completion wait
concurrent.futures.wait(futures) concurrent.futures.wait(futures)
elapsed_time = time.time() - start_time elapsed_time = time.time() - start_time

6
png.py
View file

@ -55,12 +55,12 @@ def main():
if not os.path.exists(output_folder): if not os.path.exists(output_folder):
os.makedirs(output_folder) os.makedirs(output_folder)
# Read all data from CSV at once # CSV Parse (concurrent)
with open(csv_file, newline='', encoding='utf-8') as csvfile: with open(csv_file, newline='', encoding='utf-8') as csvfile:
reader = csv.DictReader(csvfile) reader = csv.DictReader(csvfile)
participants = list(reader) participants = list(reader)
# Create a partial function with all the fixed parameters # partial function with all the fixed parameters
process_func = partial( process_func = partial(
process_certificate, process_certificate,
template_path=template_path, template_path=template_path,
@ -73,10 +73,8 @@ def main():
# Process certificates in parallel # Process certificates in parallel
with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor: with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor:
# Submit all tasks
futures = [executor.submit(process_func, row, i) for i, row in enumerate(participants, start=1)] futures = [executor.submit(process_func, row, i) for i, row in enumerate(participants, start=1)]
# Wait for all to complete
concurrent.futures.wait(futures) concurrent.futures.wait(futures)
elapsed_time = time.time() - start_time elapsed_time = time.time() - start_time