Skip to content

Commit 4cb5c15

Browse files
Adiciona método para garantir que as imagens tenham um canal alfa válido e implementa tratamento de exceções ao colar elementos no certificado, melhorando a robustez da geração de certificados.
1 parent e6e7415 commit 4cb5c15

1 file changed

Lines changed: 65 additions & 8 deletions

File tree

certified_builder/certified_builder.py

Lines changed: 65 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -83,41 +83,98 @@ def _download_image(self, url: str) -> Image:
8383
logger.error(f"Erro ao baixar imagem de {url}: {str(e)}")
8484
raise RuntimeError(f"Error downloading image from {url}: {str(e)}")
8585

86+
def _ensure_valid_rgba(self, img: Image) -> Image:
87+
"""Ensure image has a valid RGBA mode with proper transparency channel."""
88+
if img.mode != 'RGBA':
89+
img = img.convert('RGBA')
90+
91+
# Some PNG images may have problematic transparency channels
92+
# Create a new image with proper alpha channel
93+
try:
94+
new_img = Image.new('RGBA', img.size, (0, 0, 0, 0))
95+
new_img.paste(img, (0, 0), img if 'A' in img.mode else None)
96+
return new_img
97+
except Exception as e:
98+
logger.warning(f"Erro ao processar transparência, usando método alternativo: {str(e)}")
99+
# Fallback method if there's an issue with the alpha channel
100+
new_img = Image.new('RGBA', img.size, (0, 0, 0, 0))
101+
new_img.paste(img.convert('RGB'), (0, 0))
102+
return new_img
103+
86104
def generate_certificate(self, participant: Participant, certificate_template: Image, logo: Image):
87105
"""Generate a certificate for a participant."""
88106
try:
107+
# Ensure images have valid transparency channels
108+
certificate_template = self._ensure_valid_rgba(certificate_template)
109+
logo = self._ensure_valid_rgba(logo)
110+
89111
# Create transparent layer for text and logo
90112
overlay = Image.new("RGBA", certificate_template.size, (255, 255, 255, 0))
91113

92114
# Optimize logo size
93115
logo_size = (150, 150)
94116
logo = logo.resize(logo_size, Image.Resampling.LANCZOS)
95117

96-
# Paste logo
97-
padding = 50
98-
overlay.paste(logo, (padding, padding), logo)
118+
# Paste logo - handle potential transparency issues
119+
try:
120+
# Try with mask first
121+
overlay.paste(logo, (50, 50), logo)
122+
except Exception as e:
123+
logger.warning(f"Erro ao colar logo com máscara, usando método alternativo: {str(e)}")
124+
# Fallback without using the logo as its own mask
125+
overlay.paste(logo, (50, 50))
99126

100127
# Add name
101128
name_image = self.create_name_image(participant.name_completed(), certificate_template.size)
102-
overlay.paste(name_image, (0, 0), name_image)
129+
130+
# Paste with error handling
131+
try:
132+
overlay.paste(name_image, (0, 0), name_image)
133+
except Exception as e:
134+
logger.warning(f"Erro ao colar nome com máscara, usando método alternativo: {str(e)}")
135+
# Try without mask
136+
overlay.paste(name_image, (0, 0))
103137

104138
# Add details
105139
details_image = self.create_details_image(participant.certificate.details, certificate_template.size)
106140
name_center_y = certificate_template.size[1] // 2
107141
details_y = name_center_y + 50
108142

109143
details_with_position = Image.new("RGBA", certificate_template.size, (255, 255, 255, 0))
110-
details_with_position.paste(details_image, (0, details_y), details_image)
111-
overlay = Image.alpha_composite(overlay, details_with_position)
144+
145+
# Paste with error handling
146+
try:
147+
details_with_position.paste(details_image, (0, details_y), details_image)
148+
except Exception as e:
149+
logger.warning(f"Erro ao colar detalhes com máscara, usando método alternativo: {str(e)}")
150+
details_with_position.paste(details_image, (0, details_y))
151+
152+
try:
153+
overlay = Image.alpha_composite(overlay, details_with_position)
154+
except Exception as e:
155+
logger.warning(f"Erro na composição alpha, usando método alternativo: {str(e)}")
156+
# Fallback to simple paste if alpha composite fails
157+
overlay.paste(details_with_position, (0, 0))
112158

113159
# Add validation code
114160
validation_code_image = self.create_validation_code_image(participant.formated_validation_code(), certificate_template.size)
115-
overlay.paste(validation_code_image, (0, 0), validation_code_image)
161+
162+
try:
163+
overlay.paste(validation_code_image, (0, 0), validation_code_image)
164+
except Exception as e:
165+
logger.warning(f"Erro ao colar código de validação com máscara, usando método alternativo: {str(e)}")
166+
overlay.paste(validation_code_image, (0, 0))
116167

117168
# Merge and optimize final image
118169
result = Image.new("RGBA", certificate_template.size, (255, 255, 255, 0))
119170
result.paste(certificate_template, (0, 0))
120-
result = Image.alpha_composite(result, overlay)
171+
172+
try:
173+
result = Image.alpha_composite(result, overlay)
174+
except Exception as e:
175+
logger.warning(f"Erro na composição alpha final, usando método alternativo: {str(e)}")
176+
# Fallback to simple paste if alpha composite fails
177+
result.paste(overlay, (0, 0))
121178

122179
return result
123180
except Exception as e:

0 commit comments

Comments
 (0)