diff --git a/src/net/java/sip/communicator/impl/gui/main/presence/AccountStatusPanel.java b/src/net/java/sip/communicator/impl/gui/main/presence/AccountStatusPanel.java index d858d7536..fb2e8c800 100644 --- a/src/net/java/sip/communicator/impl/gui/main/presence/AccountStatusPanel.java +++ b/src/net/java/sip/communicator/impl/gui/main/presence/AccountStatusPanel.java @@ -192,8 +192,7 @@ public void run() // do not set empty images if ((accountImage != null) && (accountImage.length > 0)) - accountImageLabel - .setImageIcon(new ImageIcon(accountImage)); + accountImageLabel.setImageIcon(accountImage); String firstName = AccountInfoUtils.getFirstName(accountInfoOpSet); diff --git a/src/net/java/sip/communicator/util/ImageUtils.java b/src/net/java/sip/communicator/util/ImageUtils.java index b7301ea5d..abf661e60 100644 --- a/src/net/java/sip/communicator/util/ImageUtils.java +++ b/src/net/java/sip/communicator/util/ImageUtils.java @@ -7,7 +7,6 @@ package net.java.sip.communicator.util; import java.awt.*; -import java.awt.geom.*; import java.awt.image.*; import java.io.*; import java.net.*; @@ -58,11 +57,12 @@ public static Image scaleImageWithinBounds( Image image, } /** - * Returns the scaled icon. + * Scales the given image to fit in the given width and + * height. * @param image the image to scale - * @param width the desired width after the scale - * @param height the desired height after the scale - * @return the scaled icon + * @param width the desired width + * @param height the desired height + * @return the scaled image */ public static ImageIcon scaleIconWithinBounds(Image image, int width, int height) @@ -74,15 +74,16 @@ public static ImageIcon scaleIconWithinBounds(Image image, int width, * Creates a rounded avatar image. * * @param image image of the initial avatar image. - * @param width the desired result width - * @param height the desired result height - * @return the rounded corner image + * @param width the desired width + * @param height the desired height + * @return The rounded corner image. */ - public static Image getScaledRoundedImage(Image image, int width, int height) + public static Image getScaledRoundedImage( Image image, + int width, + int height) { ImageIcon scaledImage = ImageUtils.scaleIconWithinBounds(image, width, height); - int scaledImageWidth = scaledImage.getIconWidth(); int scaledImageHeight = scaledImage.getIconHeight(); @@ -90,34 +91,49 @@ public static Image getScaledRoundedImage(Image image, int width, int height) scaledImageWidth <= 0) return null; - RoundRectangle2D roundRect - = new RoundRectangle2D.Double( - 0, 0, scaledImageWidth, scaledImageHeight, 10, 10); + // Just clipping the image would cause jaggies on Windows and Linux. + // The following is a soft clipping solution based on the solution + // proposed by Chris Campbell: + // http://java.sun.com/mailers/techtips/corejava/2006/tt0923.html + BufferedImage destImage + = new BufferedImage(scaledImageWidth, scaledImageHeight, + BufferedImage.TYPE_INT_ARGB); - int type = BufferedImage.TYPE_INT_ARGB_PRE; - BufferedImage dstImage - = new BufferedImage(scaledImageWidth, scaledImageHeight, type); - Graphics2D g = dstImage.createGraphics(); + Graphics2D g = destImage.createGraphics(); try { + // Render our clip shape into the image. Note that we enable + // antialiasing to achieve the soft clipping effect. + g.setComposite(AlphaComposite.Src); AntialiasingManager.activateAntialiasing(g); - g.setClip(roundRect); + g.setColor(Color.WHITE); + g.fillRoundRect(0, 0, scaledImageWidth, scaledImageHeight, 15, 15); + + // We use SrcAtop, which effectively uses the + // alpha value as a coverage value for each pixel stored in the + // destination. For the areas outside our clip shape, the + // destination alpha will be zero, so nothing is rendered in those + // areas. For the areas inside our clip shape, the destination alpha + // will be fully opaque, so the full color is rendered. At the edges, + // the original antialiasing is carried over to give us the desired + // soft clipping effect. + g.setComposite(AlphaComposite.SrcAtop); g.drawImage(scaledImage.getImage(), 0, 0, null); } finally { g.dispose(); } - return dstImage; + return destImage; } /** - * Returns the scaled image in byte array. + * Returns a scaled instance of the given image. * @param image the image to scale - * @param width the desired width after the scale - * @param height the desired height after the scale - * @return the scaled image in byte array + * @param width the desired width + * @param height the desired height + * @return a byte array containing the scaled image */ public static byte[] getScaledInstanceInBytes( Image image, int width, int height) diff --git a/src/net/java/sip/communicator/util/swing/AntialiasingManager.java b/src/net/java/sip/communicator/util/swing/AntialiasingManager.java index 12c0bd709..68a5a114d 100644 --- a/src/net/java/sip/communicator/util/swing/AntialiasingManager.java +++ b/src/net/java/sip/communicator/util/swing/AntialiasingManager.java @@ -23,10 +23,9 @@ public class AntialiasingManager { * object. * @param g The Graphics object. */ - public static void activateAntialiasing(Graphics g) { - Graphics2D g2d = (Graphics2D) g; - - g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, - RenderingHints.VALUE_ANTIALIAS_ON); + public static void activateAntialiasing(Graphics g) + { + ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); } } diff --git a/src/net/java/sip/communicator/util/swing/FramedImage.java b/src/net/java/sip/communicator/util/swing/FramedImage.java index 205dee59b..d74ff7716 100644 --- a/src/net/java/sip/communicator/util/swing/FramedImage.java +++ b/src/net/java/sip/communicator/util/swing/FramedImage.java @@ -22,7 +22,7 @@ public class FramedImage { private final Image frameImage; - private Image image; + private ImageIcon icon; private final int width; @@ -53,7 +53,8 @@ public FramedImage(ImageIcon imageIcon, int width, int height) height); if (imageIcon != null) - this.setImageIcon(imageIcon); + this.icon = ImageUtils.scaleIconWithinBounds( + imageIcon.getImage(), width, height); } /** @@ -70,13 +71,11 @@ public FramedImage(int width, int height) /** * Sets the image to display in the frame. * - * @param imageIcon the image to display in the frame + * @param image the image to display in the frame */ - public void setImageIcon(ImageIcon imageIcon) + public void setImageIcon(byte[] image) { - image = ImageUtils.getScaledRoundedImage( imageIcon.getImage(), - width - 2, - height - 2); + icon = ImageUtils.getScaledRoundedIcon(image, width - 2, height - 2); if (this.isVisible()) { @@ -92,13 +91,13 @@ public void setImageIcon(ImageIcon imageIcon) */ public void paintComponent(Graphics g) { - if (image != null) + if (icon != null) { - int imageWidth = image.getWidth(this); - int imageHeight = image.getHeight(this); + int imageWidth = icon.getIconWidth(); + int imageHeight = icon.getIconHeight(); if ((imageWidth != -1) && (imageHeight != -1)) g.drawImage( - image, + icon.getImage(), width / 2 - imageWidth / 2, height / 2 - imageHeight / 2, null);