Files

349 lines
14 KiB
Java

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);
}
}