capradeepgujaran commited on
Commit
1524f36
1 Parent(s): d834ac9

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +54 -54
app.py CHANGED
@@ -391,15 +391,20 @@ class CertificateGenerator:
391
  def _add_photo(self, certificate: Image.Image, photo_path: str):
392
  """Add a clear circular profile photo in the top-right corner"""
393
  try:
 
 
 
 
394
  # Open and process photo
395
  photo = Image.open(photo_path)
 
396
 
397
- # Define size for circular photo (slightly larger for better quality)
398
  size = (120, 120)
399
 
400
- # Convert to RGBA if not already
401
- if photo.mode != 'RGBA':
402
- photo = photo.convert('RGBA')
403
 
404
  # Create high-quality circular mask
405
  mask = Image.new('L', size, 0)
@@ -409,47 +414,43 @@ class CertificateGenerator:
409
  # Resize photo maintaining aspect ratio
410
  aspect = photo.width / photo.height
411
  if aspect > 1:
412
- # Width is greater
413
  new_height = size[1]
414
  new_width = int(new_height * aspect)
415
- photo = photo.resize((new_width, new_height), Image.Resampling.LANCZOS)
416
- # Center crop
417
- left = (new_width - size[0]) // 2
418
- photo = photo.crop((left, 0, left + size[0], size[1]))
419
  else:
420
- # Height is greater
421
  new_width = size[0]
422
  new_height = int(new_width / aspect)
423
- photo = photo.resize((new_width, new_height), Image.Resampling.LANCZOS)
424
- # Center crop
 
 
 
 
 
 
425
  top = (new_height - size[1]) // 2
426
  photo = photo.crop((0, top, size[0], top + size[1]))
427
 
428
- # Create output image with transparency
429
  output = Image.new('RGBA', size, (0, 0, 0, 0))
430
  output.paste(photo, (0, 0))
431
-
432
- # Apply antialiasing to the mask
433
- mask = mask.filter(ImageFilter.GaussianBlur(radius=1))
434
  output.putalpha(mask)
435
 
436
- # Position in top-right corner with padding
437
- padding_right = 60
438
- padding_top = 40
439
- position = (certificate.width - size[0] - padding_right, padding_top)
440
 
441
- # Add a subtle white background circle for better visibility
442
  bg = Image.new('RGBA', size, (255, 255, 255, 255))
443
- bg_mask = mask.copy()
444
- certificate.paste(bg, position, mask=bg_mask)
445
 
446
  # Paste the photo
447
- certificate.paste(output, position, mask=output)
448
-
 
449
  except Exception as e:
450
  print(f"Error adding photo: {str(e)}")
451
- print(f"Photo path: {photo_path}")
452
- print(f"Photo details: {getattr(photo, 'size', 'unknown size')}, {getattr(photo, 'mode', 'unknown mode')}")
453
 
454
  def generate(
455
  self,
@@ -459,43 +460,37 @@ class CertificateGenerator:
459
  company_logo: Optional[str] = None,
460
  participant_photo: Optional[str] = None
461
  ) -> str:
462
- """Generate certificate with improved layout"""
463
  try:
464
- certificate = self._create_base_certificate()
 
465
  draw = ImageDraw.Draw(certificate)
466
 
467
- # Add professional border first
468
  self._add_professional_border(draw)
469
 
470
- # Add photo if provided (now centered)
471
- if participant_photo:
472
- self._add_photo(certificate, participant_photo)
473
- # Adjust vertical spacing for content when photo is present
474
- content_start_y = 180 # Increased to accommodate photo
475
- else:
476
- content_start_y = 140 # Original spacing when no photo
477
-
478
  # Load fonts
479
  fonts = self._load_fonts()
480
 
481
- # Add content with adjusted vertical position
482
- self._add_content(
483
- draw,
484
- fonts,
485
- str(name),
486
- str(course_name),
487
- float(score),
488
- y_offset=content_start_y
489
- )
490
-
491
  # Add company logo if provided
492
- if company_logo:
493
  self._add_logo(certificate, company_logo)
494
 
 
 
 
 
 
 
 
 
 
495
  return self._save_certificate(certificate)
496
 
497
  except Exception as e:
498
- print(f"Error generating certificate: {e}")
 
 
499
  return None
500
 
501
  def _create_base_certificate(self) -> Image.Image:
@@ -516,10 +511,15 @@ class CertificateGenerator:
516
  return certificate
517
 
518
  def _save_certificate(self, certificate: Image.Image) -> str:
519
- temp_file = tempfile.NamedTemporaryFile(delete=False, suffix='.png')
520
- certificate.save(temp_file.name, 'PNG', quality=95)
521
- return temp_file.name
522
-
 
 
 
 
 
523
 
524
  class QuizApp:
525
  def __init__(self, api_key: str):
 
391
  def _add_photo(self, certificate: Image.Image, photo_path: str):
392
  """Add a clear circular profile photo in the top-right corner"""
393
  try:
394
+ if not photo_path or not os.path.exists(photo_path):
395
+ print(f"Photo path does not exist: {photo_path}")
396
+ return
397
+
398
  # Open and process photo
399
  photo = Image.open(photo_path)
400
+ print(f"Loaded photo: {photo.size}, {photo.mode}") # Debug info
401
 
402
+ # Define size for circular photo
403
  size = (120, 120)
404
 
405
+ # Convert to RGB if not already
406
+ if photo.mode not in ('RGB', 'RGBA'):
407
+ photo = photo.convert('RGB')
408
 
409
  # Create high-quality circular mask
410
  mask = Image.new('L', size, 0)
 
414
  # Resize photo maintaining aspect ratio
415
  aspect = photo.width / photo.height
416
  if aspect > 1:
 
417
  new_height = size[1]
418
  new_width = int(new_height * aspect)
 
 
 
 
419
  else:
 
420
  new_width = size[0]
421
  new_height = int(new_width / aspect)
422
+
423
+ photo = photo.resize((new_width, max(new_height, 1)), Image.Resampling.LANCZOS)
424
+
425
+ # Center crop
426
+ if aspect > 1:
427
+ left = (new_width - size[0]) // 2
428
+ photo = photo.crop((left, 0, left + size[0], size[1]))
429
+ else:
430
  top = (new_height - size[1]) // 2
431
  photo = photo.crop((0, top, size[0], top + size[1]))
432
 
433
+ # Create circular photo
434
  output = Image.new('RGBA', size, (0, 0, 0, 0))
435
  output.paste(photo, (0, 0))
 
 
 
436
  output.putalpha(mask)
437
 
438
+ # Position in top-right corner
439
+ photo_x = certificate.width - size[0] - 60 # 60px from right
440
+ photo_y = 40 # 40px from top
 
441
 
442
+ # Add white background circle
443
  bg = Image.new('RGBA', size, (255, 255, 255, 255))
444
+ certificate.paste(bg, (photo_x, photo_y), mask=mask)
 
445
 
446
  # Paste the photo
447
+ certificate.paste(output, (photo_x, photo_y), mask=output)
448
+ print(f"Successfully added photo at position ({photo_x}, {photo_y})")
449
+
450
  except Exception as e:
451
  print(f"Error adding photo: {str(e)}")
452
+ import traceback
453
+ traceback.print_exc()
454
 
455
  def generate(
456
  self,
 
460
  company_logo: Optional[str] = None,
461
  participant_photo: Optional[str] = None
462
  ) -> str:
463
+ """Generate certificate with improved photo handling"""
464
  try:
465
+ # Create base certificate
466
+ certificate = Image.new('RGB', self.certificate_size, self.background_color)
467
  draw = ImageDraw.Draw(certificate)
468
 
469
+ # Add border
470
  self._add_professional_border(draw)
471
 
 
 
 
 
 
 
 
 
472
  # Load fonts
473
  fonts = self._load_fonts()
474
 
 
 
 
 
 
 
 
 
 
 
475
  # Add company logo if provided
476
+ if company_logo and os.path.exists(company_logo):
477
  self._add_logo(certificate, company_logo)
478
 
479
+ # Add participant photo if provided
480
+ if participant_photo:
481
+ print(f"Processing photo: {participant_photo}") # Debug info
482
+ self._add_photo(certificate, participant_photo)
483
+
484
+ # Add content
485
+ self._add_content(draw, fonts, str(name), str(course_name), float(score))
486
+
487
+ # Save certificate
488
  return self._save_certificate(certificate)
489
 
490
  except Exception as e:
491
+ print(f"Error generating certificate: {str(e)}")
492
+ import traceback
493
+ traceback.print_exc()
494
  return None
495
 
496
  def _create_base_certificate(self) -> Image.Image:
 
511
  return certificate
512
 
513
  def _save_certificate(self, certificate: Image.Image) -> str:
514
+ """Save certificate with improved error handling"""
515
+ try:
516
+ temp_file = tempfile.NamedTemporaryFile(delete=False, suffix='.png')
517
+ certificate.save(temp_file.name, 'PNG', quality=95)
518
+ print(f"Certificate saved to: {temp_file.name}") # Debug info
519
+ return temp_file.name
520
+ except Exception as e:
521
+ print(f"Error saving certificate: {str(e)}")
522
+ return None
523
 
524
  class QuizApp:
525
  def __init__(self, api_key: str):