Some days ago I've tried to fix incorrect rendering of avatar on Mac OSX by using clipping instead of AlphaComposite for obtaining a rounded image. Unfortunately this approach solved the initial problem, but introduced another one:( Jiggies appeard on avatars on Windows and Linux, which appeared to be a known issue of clipping. Thus I came back to our previous solution now and fixed the initial problem by using ImageIO to create the avatar image from bytes instead of ImageIcon, which apparently sets some specific properties to the image, which prevents the AlphaComposite to work properly. In result, avatars should be rendered correctly on all operating systems now.

cusax-fix
Yana Stamcheva 17 years ago
parent b917bbc4bd
commit 09cc8bb20b

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

@ -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 <tt>image</tt> to fit in the given <tt>width</tt> and
* <tt>height</tt>.
* @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 <tt>image</tt>.
* @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)

@ -23,10 +23,9 @@ public class AntialiasingManager {
* object.
* @param g The <tt>Graphics</tt> 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);
}
}

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

Loading…
Cancel
Save