import java.awt.*; import java.awt.geom.*; import java.awt.image.BufferedImage; import java.io.File; import javax.imageio.ImageIO; public class GeneratePngAssets { public static void main(String[] args) throws Exception { File outDir = new File("assets/images"); outDir.mkdirs(); generateAppIcon(new File(outDir, "app-icon.png"), 256); generateAppLogo(new File(outDir, "app-logo.png"), 480, 120); generateBrandBanner(new File(outDir, "brand-banner.png"), 600, 160); generateDefaultSeal(new File(outDir, "default-seal.png"), 640, 164); System.out.println("Imagens PNG geradas com sucesso em assets/images/"); } private static void setupHints(Graphics2D g2) { g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC); } /** * Gera app-icon.png (Ícone de alta fidelidade com Cristal / Diamante Azul Serpro 3D) */ private static void generateAppIcon(File file, int size) throws Exception { BufferedImage img = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB); Graphics2D g2 = img.createGraphics(); setupHints(g2); // Fundo com cantos arredondados e gradiente azul profundo double arc = size * 0.28; RoundRectangle2D bg = new RoundRectangle2D.Double(8, 8, size - 16, size - 16, arc, arc); Paint bgPaint = new LinearGradientPaint( 0, 0, size, size, new float[]{0.0f, 0.45f, 1.0f}, new Color[]{new Color(0x1976d2), new Color(0x0d47a1), new Color(0x01579b)} ); g2.setPaint(bgPaint); g2.fill(bg); // Borda sutil de brilho interno g2.setColor(new Color(255, 255, 255, 60)); g2.setStroke(new BasicStroke(size * 0.015f)); g2.draw(new RoundRectangle2D.Double(10, 10, size - 20, size - 20, arc - 4, arc - 4)); // Facetas cristalinas em 3D double s = size; Path2D topFacet = new Path2D.Double(); topFacet.moveTo(s * 0.50, s * 0.18); topFacet.lineTo(s * 0.82, s * 0.44); topFacet.lineTo(s * 0.50, s * 0.56); topFacet.lineTo(s * 0.18, s * 0.44); topFacet.closePath(); Paint topPaint = new LinearGradientPaint( (float)(s * 0.5), (float)(s * 0.18), (float)(s * 0.5), (float)(s * 0.56), new float[]{0.0f, 1.0f}, new Color[]{new Color(255, 255, 255, 230), new Color(128, 216, 255, 140)} ); g2.setPaint(topPaint); g2.fill(topFacet); Path2D leftFacet = new Path2D.Double(); leftFacet.moveTo(s * 0.18, s * 0.44); leftFacet.lineTo(s * 0.50, s * 0.56); leftFacet.lineTo(s * 0.50, s * 0.84); leftFacet.lineTo(s * 0.28, s * 0.70); leftFacet.closePath(); Paint leftPaint = new LinearGradientPaint( (float)(s * 0.18), (float)(s * 0.44), (float)(s * 0.50), (float)(s * 0.84), new float[]{0.0f, 1.0f}, new Color[]{new Color(64, 196, 255, 180), new Color(2, 136, 209, 90)} ); g2.setPaint(leftPaint); g2.fill(leftFacet); Path2D rightFacet = new Path2D.Double(); rightFacet.moveTo(s * 0.82, s * 0.44); rightFacet.lineTo(s * 0.50, s * 0.56); rightFacet.lineTo(s * 0.50, s * 0.84); rightFacet.lineTo(s * 0.72, s * 0.70); rightFacet.closePath(); Paint rightPaint = new LinearGradientPaint( (float)(s * 0.82), (float)(s * 0.44), (float)(s * 0.50), (float)(s * 0.84), new float[]{0.0f, 1.0f}, new Color[]{new Color(225, 245, 254, 210), new Color(41, 182, 246, 120)} ); g2.setPaint(rightPaint); g2.fill(rightFacet); // Brilho estelar central RadialGradientPaint glow = new RadialGradientPaint( (float)(s * 0.5), (float)(s * 0.5), (float)(s * 0.16), new float[]{0.0f, 1.0f}, new Color[]{new Color(255, 255, 255, 240), new Color(255, 255, 255, 0)} ); g2.setPaint(glow); g2.fill(new Ellipse2D.Double(s * 0.34, s * 0.34, s * 0.32, s * 0.32)); g2.dispose(); ImageIO.write(img, "PNG", file); } /** * Gera app-logo.png (Logotipo Horizontal com Cristal + Texto CyberCore SIGNER) */ private static void generateAppLogo(File file, int width, int height) throws Exception { BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); Graphics2D g2 = img.createGraphics(); setupHints(g2); // Ícone cristal no canto esquerdo int iconSize = 88; int iconX = 14; int iconY = 16; RoundRectangle2D bg = new RoundRectangle2D.Double(iconX, iconY, iconSize, iconSize, 24, 24); Paint bgPaint = new LinearGradientPaint( iconX, iconY, iconX + iconSize, iconY + iconSize, new float[]{0.0f, 0.5f, 1.0f}, new Color[]{new Color(0x1976d2), new Color(0x0d47a1), new Color(0x01579b)} ); g2.setPaint(bgPaint); g2.fill(bg); // Cristal no ícone double cx = iconX + iconSize * 0.5; double cy = iconY + iconSize * 0.5; double sz = iconSize * 0.72; Path2D topFacet = new Path2D.Double(); topFacet.moveTo(cx, cy - sz * 0.45); topFacet.lineTo(cx + sz * 0.45, cy - sz * 0.08); topFacet.lineTo(cx, cy + sz * 0.1); topFacet.lineTo(cx - sz * 0.45, cy - sz * 0.08); topFacet.closePath(); g2.setPaint(new Color(255, 255, 255, 220)); g2.fill(topFacet); Path2D botFacet = new Path2D.Double(); botFacet.moveTo(cx - sz * 0.45, cy - sz * 0.08); botFacet.lineTo(cx, cy + sz * 0.1); botFacet.lineTo(cx, cy + sz * 0.50); botFacet.lineTo(cx - sz * 0.30, cy + sz * 0.30); botFacet.closePath(); g2.setPaint(new Color(64, 196, 255, 180)); g2.fill(botFacet); Path2D rightFacet = new Path2D.Double(); rightFacet.moveTo(cx + sz * 0.45, cy - sz * 0.08); rightFacet.lineTo(cx, cy + sz * 0.1); rightFacet.lineTo(cx, cy + sz * 0.50); rightFacet.lineTo(cx + sz * 0.30, cy + sz * 0.30); rightFacet.closePath(); g2.setPaint(new Color(225, 245, 254, 220)); g2.fill(rightFacet); // Tipografia int textX = iconX + iconSize + 22; // "CyberCore" g2.setFont(new Font("Segoe UI", Font.BOLD, 42)); g2.setColor(new Color(0x0a2540)); g2.drawString("Cyber", textX, 62); int cyberWidth = g2.getFontMetrics().stringWidth("Cyber"); g2.setColor(new Color(0x0288d1)); g2.drawString("Core", textX + cyberWidth, 62); // Badge "SIGNER" int badgeX = textX; int badgeY = 74; int badgeW = 100; int badgeH = 24; g2.setColor(new Color(0x0288d1)); g2.fill(new RoundRectangle2D.Double(badgeX, badgeY, badgeW, badgeH, 6, 6)); g2.setFont(new Font("Segoe UI", Font.BOLD, 14)); g2.setColor(Color.WHITE); g2.drawString("SIGNER", badgeX + 22, badgeY + 17); // Subtítulo g2.setFont(new Font("Segoe UI", Font.PLAIN, 13)); g2.setColor(new Color(0x64748b)); g2.drawString("ICP-Brasil • Assinador Digital Seguro", badgeX + badgeW + 12, badgeY + 17); g2.dispose(); ImageIO.write(img, "PNG", file); } /** * Gera brand-banner.png (Banner institucional de cabeçalho e documentação) */ private static void generateBrandBanner(File file, int width, int height) throws Exception { BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); Graphics2D g2 = img.createGraphics(); setupHints(g2); // Fundo com cantos arredondados e gradiente moderno Serpro Blue RoundRectangle2D rect = new RoundRectangle2D.Double(0, 0, width, height, 16, 16); Paint grad = new LinearGradientPaint( 0, 0, width, height, new float[]{0.0f, 0.6f, 1.0f}, new Color[]{new Color(0x0d47a1), new Color(0x0284c7), new Color(0x0369a1)} ); g2.setPaint(grad); g2.fill(rect); // Elementos gráficos decorativos de fundo g2.setColor(new Color(255, 255, 255, 25)); g2.fill(new Ellipse2D.Double(width - 180, -40, 220, 220)); g2.fill(new Ellipse2D.Double(width - 90, 60, 160, 160)); // Cristal no canto esquerdo int iconSize = 90; int iconX = 30; int iconY = 35; RoundRectangle2D iconBg = new RoundRectangle2D.Double(iconX, iconY, iconSize, iconSize, 22, 22); g2.setPaint(new LinearGradientPaint( iconX, iconY, iconX + iconSize, iconY + iconSize, new float[]{0.0f, 1.0f}, new Color[]{new Color(0x1e88e5), new Color(0x01579b)} )); g2.fill(iconBg); // Detalhe de luz no ícone g2.setColor(Color.WHITE); g2.setStroke(new BasicStroke(2f)); g2.draw(new RoundRectangle2D.Double(iconX + 3, iconY + 3, iconSize - 6, iconSize - 6, 18, 18)); // Diamante interno double cx = iconX + iconSize * 0.5; double cy = iconY + iconSize * 0.5; Path2D diamond = new Path2D.Double(); diamond.moveTo(cx, cy - 28); diamond.lineTo(cx + 26, cy); diamond.lineTo(cx, cy + 28); diamond.lineTo(cx - 26, cy); diamond.closePath(); g2.setPaint(new Color(255, 255, 255, 220)); g2.fill(diamond); // Textos no Banner int textX = iconX + iconSize + 28; g2.setFont(new Font("Segoe UI", Font.BOLD, 36)); g2.setColor(Color.WHITE); g2.drawString("CyberCore Signer", textX, 74); g2.setFont(new Font("Segoe UI", Font.PLAIN, 16)); g2.setColor(new Color(0xe0f2fe)); g2.drawString("Agente de Assinatura Digital ICP-Brasil A1 & A3", textX, 104); g2.setFont(new Font("Segoe UI", Font.BOLD, 12)); g2.setColor(new Color(0x38bdf8)); g2.drawString("PADES • XADES • CADES • TIMESTAMPS • CCSP/1", textX, 128); g2.dispose(); ImageIO.write(img, "PNG", file); } /** * Gera default-seal.png (Selo de Assinatura Digital Elegante com Brasão e Textos) */ private static void generateDefaultSeal(File file, int width, int height) throws Exception { BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); Graphics2D g2 = img.createGraphics(); setupHints(g2); // Fundo do selo com leve transparência e borda azul RoundRectangle2D sealBox = new RoundRectangle2D.Double(2, 2, width - 4, height - 4, 12, 12); g2.setColor(new Color(248, 250, 252, 245)); g2.fill(sealBox); g2.setColor(new Color(0x0288d1)); g2.setStroke(new BasicStroke(2.5f)); g2.draw(sealBox); // Brasão Notarial no lado esquerdo int badgeX = 18; int badgeY = 16; int badgeW = 130; int badgeH = height - 32; RoundRectangle2D badgeBg = new RoundRectangle2D.Double(badgeX, badgeY, badgeW, badgeH, 10, 10); g2.setPaint(new LinearGradientPaint( badgeX, badgeY, badgeX, badgeY + badgeH, new float[]{0.0f, 1.0f}, new Color[]{new Color(0x0288d1), new Color(0x01579b)} )); g2.fill(badgeBg); // Escudo e Estrela no Brasão g2.setColor(Color.WHITE); g2.setFont(new Font("Segoe UI", Font.BOLD, 13)); g2.drawString("ASSINADO", badgeX + 28, badgeY + 40); g2.drawString("DIGITALMENTE", badgeX + 16, badgeY + 58); // Estrela dourada g2.setColor(new Color(0xfbbf24)); g2.fill(new Ellipse2D.Double(badgeX + badgeW * 0.5 - 12, badgeY + 74, 24, 24)); g2.setColor(Color.WHITE); g2.setFont(new Font("Segoe UI", Font.BOLD, 16)); g2.drawString("★", (int)(badgeX + badgeW * 0.5 - 7), badgeY + 92); g2.setFont(new Font("Segoe UI", Font.PLAIN, 10)); g2.setColor(new Color(0xe0f2fe)); g2.drawString("ICP-BRASIL", badgeX + 34, badgeY + 118); // Linha divisória vertical int divX = badgeX + badgeW + 18; g2.setColor(new Color(0xcfd8dc)); g2.setStroke(new BasicStroke(1.5f)); g2.drawLine(divX, 16, divX, height - 16); // Área textual de informações da assinatura int textX = divX + 18; g2.setColor(new Color(0x64748b)); g2.setFont(new Font("Segoe UI", Font.BOLD, 11)); g2.drawString("DOCUMENTO ASSINADO DIGITALMENTE POR:", textX, 36); g2.setColor(new Color(0x0a2540)); g2.setFont(new Font("Segoe UI", Font.BOLD, 18)); g2.drawString("JOÃO DA SILVA SAUDÁVEL", textX, 60); g2.setColor(new Color(0x334155)); g2.setFont(new Font("Segoe UI", Font.PLAIN, 12)); g2.drawString("CPF: ***.456.789-**", textX, 82); g2.drawString("Data e Hora: 09/10/2026 20:30:00 -03:00", textX, 102); // Rodapé de autenticação g2.setColor(new Color(0x0288d1)); g2.setFont(new Font("Segoe UI", Font.ITALIC, 11)); g2.drawString("A conformidade com a ICP-Brasil pode ser verificada no ITI.", textX, 128); g2.dispose(); ImageIO.write(img, "PNG", file); } }