Imagem com cantos arredondados no Java

Imagem com canto arredondado em Java

De uns tempos para cá notei uma nova onda dos desenvolvedores em arredondar os cantos da imagens para ficar mais estiloso, realmente o resultado fica bem mais agradável, então vamos ver como se faz isso em Java, vamos começar com o que mais interessa a todos, o código fonte da mágica:

class RoundImage {
 
private static final Stroke stroke = new BasicStroke(1.5f);
 
private RoundImage() { }
 
public static Image getRoundImage(Image imageSource, int radius) {
int width = imageSource.getWidth(null);
int height = imageSource.getHeight(null);
 
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
RoundRectangle2D rect = new RoundRectangle2D.Double(0, 0, width, height, radius, radius);
 
Graphics2D g2 = (Graphics2D) image.getGraphics();
 
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
 
g2.clip(rect);
g2.drawImage(imageSource, 0, 0, null);
 
g2.setStroke(stroke);
g2.setColor(Color.WHITE);
g2.draw(rect);
 
return image;
}
}

O truque baseia-se em criar uma nova instância de BufferedImage com suporte ao canal alpha e restringir a área de trabalho do graphics para um shape do tipo RoundRectangle2D através do método clip presente na classe Graphics2D, após isso é só mandar pintar a imagem original em nossa nova imagem com suporte a alpha e restrição aos cantos para ficar arredondado.

Existe um probleminha, quando utilizamos o clip do objeto Graphics2D, não obtemos o recurso de antialising porque o mesmo não o fornece através do clip, então para conseguirmos o efeito de suavidade desejada nos cantos arredondados podemos fazer um workaround quase inperceptível aí, desenhe um RoundRectangle2D (sem preenchimento, lógico) usando uma cor aproximada ao background, no caso utilizei o branco por ser uma cor que se mistura facilmente com várias outras cores.

Abaixo segue o código fonte de um exemplo de utilização que produz a imagem de exemplo no começo do post.

public class RoundImageSample extends JFrame {
 
public RoundImageSample() {
initComponents();
 
try {
ImageIcon icon = new ImageIcon(new URL("http://www.paulocanedo.com.br/imagens/brasil.jpg"));
 
roundImageLabel.setIcon(new ImageIcon(RoundImage.getRoundImage(icon.getImage(), 30)));
} catch (MalformedURLException ex) {
ex.printStackTrace();
}
}
 
private void initComponents() {
roundImageLabel = new javax.swing.JLabel();
 
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setTitle("RoundImage, paulocanedo.com.br");
getContentPane().setLayout(new java.awt.GridLayout());
 
roundImageLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
getContentPane().add(roundImageLabel);
 
java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
setBounds((screenSize.width-420)/2, (screenSize.height-280)/2, 420, 280);
}
 
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
 
public void run() {
new RoundImageSample().setVisible(true);
}
});
}
 
private JLabel roundImageLabel;
}

Alterando o Java padrão no linux Ubuntu

Uma coisa que acho muito incômoda no ubuntu é o fato de, sempre que um nova distribuição Java é instalada o Java padrão do sistema é alterado, isso acontece as vezes sem mesmo que a gente perceba, quando você quer o sun-java instalado por padrão é quase impossível não instalar um outro aplicativo que adicione como dependência outro java (muitas vezes o open-jdk) e esse novo passa a assumir o papel do java padrão.

Para resolver isso um truque muito simples pelo terminal resolve o problema:

sudo update-alternatives --config java

Alterando o Java padrão do Ubuntu

←Older