capradeepgujaran commited on
Commit
13df159
1 Parent(s): 6a51b6d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +96 -37
app.py CHANGED
@@ -300,8 +300,63 @@ class CertificateGenerator:
300
  [(1160, 780 - corner_size), (1160, 780)]
301
  ]
302
 
303
- for corner in corners:
304
- draw.line(corner, fill=self.border_color, width=2)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
305
 
306
  def _add_content(
307
  self,
@@ -311,45 +366,49 @@ class CertificateGenerator:
311
  course_name: str,
312
  score: float
313
  ):
314
- # Title and headers
315
- draw.text((600, 100), "CertifyMe AI", font=fonts['title'], fill=self.border_color, anchor="mm")
316
- draw.text((600, 160), "Certificate of Achievement", font=fonts['subtitle'], fill=self.border_color, anchor="mm")
317
-
318
- # Clean inputs
319
- name = str(name).strip() or "Participant"
320
- course_name = str(course_name).strip() or "Assessment"
321
-
322
- # Main content
323
- content = [
324
- (300, "This is to certify that", 'black'),
325
- (380, name, self.border_color),
326
- (460, "has successfully completed", 'black'),
327
- (540, course_name, self.border_color),
328
- (620, f"with a score of {float(score):.1f}%", 'black'),
329
- (700, datetime.now().strftime("%B %d, %Y"), 'black')
330
- ]
331
 
332
- for y, text, color in content:
333
- draw.text((600, y), text, font=fonts['text'], fill=color, anchor="mm")
334
-
335
- def _add_images(
336
- self,
337
- certificate: Image.Image,
338
- company_logo: Optional[str],
339
- participant_photo: Optional[str]
340
- ):
341
- if company_logo:
342
- self._add_image(certificate, company_logo, (50, 50))
343
- if participant_photo:
344
- self._add_image(certificate, participant_photo, (1000, 50))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
345
 
346
- def _add_image(self, certificate: Image.Image, image_path: str, position: Tuple[int, int]):
347
  try:
348
- img = Image.open(image_path)
349
- img.thumbnail((150, 150))
350
- certificate.paste(img, position)
 
 
351
  except Exception as e:
352
- print(f"Error adding image: {e}")
353
 
354
  def _save_certificate(self, certificate: Image.Image) -> str:
355
  temp_file = tempfile.NamedTemporaryFile(delete=False, suffix='.png')
 
300
  [(1160, 780 - corner_size), (1160, 780)]
301
  ]
302
 
303
+ class CertificateGenerator:
304
+ def __init__(self):
305
+ self.certificate_size = (1200, 800)
306
+ self.border_color = '#FFFFFF' # White background
307
+ self.background_color = '#FFFFFF'
308
+
309
+ # Install fonts if needed
310
+ FontManager.install_fonts()
311
+ self.font_paths = FontManager.get_font_paths()
312
+
313
+ def _load_fonts(self) -> Dict[str, ImageFont.FreeTypeFont]:
314
+ """Load fonts with fallbacks"""
315
+ fonts = {}
316
+ try:
317
+ if self.font_paths['regular'] and self.font_paths['bold']:
318
+ fonts['title'] = ImageFont.truetype(self.font_paths['bold'], 36) # Smaller for course name
319
+ fonts['subtitle'] = ImageFont.truetype(self.font_paths['regular'], 14) # For labels
320
+ fonts['text'] = ImageFont.truetype(self.font_paths['regular'], 20) # For regular text
321
+ fonts['name'] = ImageFont.truetype(self.font_paths['bold'], 32) # For participant name
322
+ else:
323
+ raise ValueError("No suitable fonts found")
324
+ except Exception as e:
325
+ print(f"Font loading error: {e}. Using default font.")
326
+ default = ImageFont.load_default()
327
+ fonts = {
328
+ 'title': default,
329
+ 'subtitle': default,
330
+ 'text': default,
331
+ 'name': default
332
+ }
333
+ return fonts
334
+
335
+ def generate(
336
+ self,
337
+ score: float,
338
+ name: str,
339
+ course_name: str,
340
+ company_logo: Optional[str] = None,
341
+ participant_photo: Optional[str] = None
342
+ ) -> str:
343
+ try:
344
+ certificate = self._create_base_certificate()
345
+ draw = ImageDraw.Draw(certificate)
346
+
347
+ fonts = self._load_fonts()
348
+ self._add_content(draw, fonts, str(name), str(course_name), float(score))
349
+
350
+ if company_logo:
351
+ self._add_logo(certificate, company_logo)
352
+
353
+ return self._save_certificate(certificate)
354
+ except Exception as e:
355
+ print(f"Error generating certificate: {e}")
356
+ return None
357
+
358
+ def _create_base_certificate(self) -> Image.Image:
359
+ return Image.new('RGB', self.certificate_size, self.background_color)
360
 
361
  def _add_content(
362
  self,
 
366
  course_name: str,
367
  score: float
368
  ):
369
+ # Add certificate ID at top right
370
+ certificate_id = f"Certificate no: {datetime.now().strftime('%Y%m%d')}-{abs(hash(name)) % 10000:04d}"
371
+ draw.text((1100, 40), certificate_id, font=fonts['subtitle'], fill='#666666', anchor="ra")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
372
 
373
+ # Add "CERTIFICATE OF COMPLETION" text
374
+ draw.text((60, 120), "CERTIFICATE OF COMPLETION", font=fonts['subtitle'], fill='#666666')
375
+
376
+ # Add course name (large and bold)
377
+ course_name = course_name.strip() or "Assessment"
378
+ draw.multiline_text((60, 180), course_name, font=fonts['title'], fill='#1C1D1F', spacing=10)
379
+
380
+ # Add instructor info
381
+ draw.text((60, 280), "Instructor", font=fonts['subtitle'], fill='#666666')
382
+ draw.text((60, 310), "CertifyMe AI", font=fonts['text'], fill='#1C1D1F')
383
+
384
+ # Add participant name (large)
385
+ name = name.strip() or "Participant"
386
+ draw.text((60, 400), name, font=fonts['name'], fill='#1C1D1F')
387
+
388
+ # Add date and score info with spacing
389
+ date_str = datetime.now().strftime("%b. %d, %Y")
390
+
391
+ # Date section
392
+ draw.text((60, 480), "Date", font=fonts['subtitle'], fill='#666666')
393
+ draw.text((60, 510), date_str, font=fonts['text'], fill='#1C1D1F')
394
+
395
+ # Score section
396
+ draw.text((300, 480), "Score", font=fonts['subtitle'], fill='#666666')
397
+ draw.text((300, 510), f"{float(score):.1f}%", font=fonts['text'], fill='#1C1D1F')
398
+
399
+ # Add reference number at bottom
400
+ ref_number = f"Reference Number: {abs(hash(name + date_str)) % 10000:04d}"
401
+ draw.text((60, 700), ref_number, font=fonts['subtitle'], fill='#666666')
402
 
403
+ def _add_logo(self, certificate: Image.Image, logo_path: str):
404
  try:
405
+ logo = Image.open(logo_path)
406
+ # Resize logo to appropriate size
407
+ logo.thumbnail((150, 80))
408
+ # Position in top-left corner
409
+ certificate.paste(logo, (50, 30))
410
  except Exception as e:
411
+ print(f"Error adding logo: {e}")
412
 
413
  def _save_certificate(self, certificate: Image.Image) -> str:
414
  temp_file = tempfile.NamedTemporaryFile(delete=False, suffix='.png')