@@ -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