diff --git a/process_images.py b/process_images.py index 3e1b8e1..15290ee 100644 --- a/process_images.py +++ b/process_images.py @@ -1,7 +1,7 @@ from PIL import Image import numpy as np -def remove_black_background(img_path, out_path): +def remove_black_background(img_path, out_path, t_low=32, t_high=80): # Carregar imagem e garantir modo RGBA img = Image.open(img_path).convert("RGBA") data = np.array(img) @@ -9,41 +9,57 @@ def remove_black_background(img_path, out_path): # Extrair canais r, g, b, a = data[:,:,0], data[:,:,1], data[:,:,2], data[:,:,3] - # O alpha original é estimado pelo valor máximo dos canais R, G, B - # Isso funciona porque o fundo é preto (0,0,0) - # Usamos fmax para obter o valor float e evitar overflow/underflow + # O valor de brilho de cada pixel é dado pelo máximo dos canais R, G, B max_rgb = np.fmax(np.fmax(r, g), b) # Criar nova imagem com o mesmo tamanho new_data = np.zeros_like(data) - # O novo alpha é o valor máximo de R, G, B - new_alpha = max_rgb.astype(np.uint8) + # Calcular o novo alpha com base na rampa de threshold + # Se max_rgb <= t_low -> alpha = 0 + # Se max_rgb >= t_high -> alpha = max_rgb (ou 255 se quisermos opacidade total) + # Se t_low < max_rgb < t_high -> interpolação linear - # Onde new_alpha é maior que zero, desmultiplicamos a cor para remover o halo preto - mask = new_alpha > 0 + new_alpha = np.zeros_like(max_rgb, dtype=float) - # Copiar canais - new_data[:,:,0] = r - new_data[:,:,1] = g - new_data[:,:,2] = b - new_data[:,:,3] = new_alpha + # Máscara para pixels totalmente opacos (ou usando o brilho original) + mask_full = max_rgb >= t_high + # Opcionalmente, definimos opacidade 255 para o miolo brilhante do logotipo para ficar bem nítido + new_alpha[mask_full] = 255.0 - # Aplicar unmultiplying alpha para clarear os pixels semi-transparentes de borda - # R_new = R_old * 255 / alpha - alpha_float = new_alpha.astype(float) + # Máscara para pixels de transição (antialiasing) + mask_trans = (max_rgb > t_low) & (max_rgb < t_high) + new_alpha[mask_trans] = 255.0 * (max_rgb[mask_trans] - t_low) / (t_high - t_low) + + # Converter alpha final para uint8 + final_alpha = np.clip(new_alpha, 0, 255).astype(np.uint8) + + # Máscara de pixels visíveis + mask_visible = final_alpha > 0 + + # Inicializar os canais de cores com zeros + new_data[:,:,0] = 0 + new_data[:,:,1] = 0 + new_data[:,:,2] = 0 + new_data[:,:,3] = final_alpha + + # Aplicar unmultiplying alpha nas cores para remover o halo escuro e clarear pixels de transição + alpha_float = final_alpha.astype(float) for i in range(3): channel = data[:,:,i].astype(float) - # Onde a máscara for verdadeira, calcula. Onde for falsa, deixa zero. adjusted = np.zeros_like(channel) - adjusted[mask] = np.minimum(255, (channel[mask] * 255.0 / alpha_float[mask])) + # Onde for visível, recuperamos a cor original. + # Para evitar divisão por zero, usamos a máscara de pixels visíveis + adjusted[mask_visible] = np.minimum(255, (channel[mask_visible] * 255.0 / np.maximum(1.0, max_rgb[mask_visible]))) new_data[:,:,i] = adjusted.astype(np.uint8) # Salvar a nova imagem out_img = Image.fromarray(new_data, "RGBA") out_img.save(out_path, "PNG") - print(f"Processada: {img_path} -> {out_path}") + print(f"Processada com sucesso: {img_path} -> {out_path} (T_low: {t_low}, T_high: {t_high})") if __name__ == "__main__": - remove_black_background("logotipo_steelXR.png", "public/logotipo_steelXR_transparente.png") - remove_black_background("iconeXR.png", "public/iconeXR_transparente.png") + # O logotipo tem fundo com brilho aproximado de 28 + remove_black_background("logotipo_steelXR.png", "public/logotipo_steelXR_transparente.png", t_low=32, t_high=75) + # O ícone tem fundo com brilho de 9 + remove_black_background("iconeXR.png", "public/iconeXR_transparente.png", t_low=12, t_high=50) diff --git a/public/favicon.ico b/public/favicon.ico index bff3238..df0760e 100644 Binary files a/public/favicon.ico and b/public/favicon.ico differ diff --git a/public/iconeXR_transparente.png b/public/iconeXR_transparente.png index 93f0bba..6c0ba90 100644 Binary files a/public/iconeXR_transparente.png and b/public/iconeXR_transparente.png differ diff --git a/public/logotipo_steelXR_transparente.png b/public/logotipo_steelXR_transparente.png index 35c13cd..72408d9 100644 Binary files a/public/logotipo_steelXR_transparente.png and b/public/logotipo_steelXR_transparente.png differ