Hello,
I am currently in the process of migrating my application (IMS.Server) from windows
to Linux. One of the last problems I face is a piece of code, which works on windows,
but fails on Linux. I tried a couple of days, and googled, but so far with no success.
The piece of code which fails prints a text onto a buffered imaged. I made an excerpt
of the code, put that into one class. It runs on Windows, fails on Linux (Fedora Core 2).
Here is the code:
/*
* Created on Oct 27, 2004
*
* TODO To change the template for this generated file go to
* Window - Preferences - Java - Code Style - Code Templates
*/
import java.awt.image.BufferedImage;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.font.FontRenderContext;
import java.awt.font.TextAttribute;
import java.awt.font.TextLayout;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.text.AttributedCharacterIterator;
import java.text.AttributedString;
/**
* @author rm11-rolf
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
public class ThumbnailGenerationTestX {
public static void main(String[] args) {
doThumbnailGenerationTest();
}
public static void doThumbnailGenerationTest() {
int sizeW = 1024;
int sizeH = 768;
System.out.println("sizeW = " + sizeW);
System.out.println("sizeH = " + sizeH);
System.out.println();
String myText = "(c) by Rolf Mueller";
String fontName = "serif";
int fontSize = 32;
int fontAtt = Font.BOLD;
Font font = new Font(fontName, fontAtt, fontSize);
AttributedString as = new AttributedString(myText);
as.addAttribute(TextAttribute.FONT,font,0,myText.length());
Color blackColor = new Color(255,255,255);
as.addAttribute(TextAttribute.FOREGROUND,blackColor,0,myText.length());
System.out.println("myText = " + myText);
System.out.println("fontName = " + fontName);
System.out.println("fontSize = " + fontSize);
System.out.println();
// Create empty Image...
BufferedImage bgImage = new BufferedImage(sizeW,sizeH,BufferedImage.TYPE_INT_RGB);
Graphics2D bgG2d = bgImage.createGraphics();
// calculate the width of the text
TextLayout tl2d = getBoundsFromString(as,bgG2d);
Rectangle2D ra2d = tl2d.getBounds();
int textWidth = (int)ra2d.getWidth();
int textHeight = (int)ra2d.getHeight();
int textAscent = (int)tl2d.getAscent();
int textDescent = (int)tl2d.getDescent();
System.out.println("textWidth = " + textWidth);
System.out.println("textHeight = " + textHeight);
System.out.println("textAscent = " + textAscent);
System.out.println("textDescent = " + textDescent);
System.out.println();
// Create an image buffer for the forground with the text
BufferedImage fgImage = new BufferedImage(textWidth, textAscent, BufferedImage.TYPE_INT_RGB);
Graphics2D fgG2d = fgImage.createGraphics();
AffineTransform fontAT = new AffineTransform();
AttributedCharacterIterator aci = as.getIterator();
fgG2d.drawString(aci,0,textHeight-textDescent);
fgG2d.dispose();
// calculate the position (which is lower right)
int offset = sizeH / 100;
int textXPos = sizeW - textWidth - offset;
int textYPos = sizeH - offset - textHeight;
System.out.println("offset = " + offset);
System.out.println("textXPos = " + textXPos);
System.out.println("textYPos = " + textYPos);
System.out.println();
// get the background image pixels
int[] bgPixels = new int[ textWidth * textHeight ];
bgPixels = bgImage.getRGB( textXPos, textYPos, textWidth, textHeight, bgPixels, 0, textWidth );
// get the forground image pixels
int[] fgPixels = new int[ textWidth * textHeight * 10 ];
try {
fgPixels = fgImage.getRGB( 0, 0, textWidth, textHeight, fgPixels, 0, textWidth );
} catch (Exception ex) {
ex.printStackTrace();
}
System.out.println("Finished successfully!");
}
/**
* getBoundsFromString()
* retrieves the boundaries of a String
* @param as
* @param g2d
* @return TextLayout
*/
private static TextLayout getBoundsFromString(AttributedString as, Graphics2D g2d) {
AttributedCharacterIterator attribCharIterator = as.getIterator();
FontRenderContext frc = g2d.getFontRenderContext();
TextLayout tl = new TextLayout(attribCharIterator,frc);
return tl;
}
}
Ok, here is the result, when I run it on a Linux Box:
sizeW = 1024
sizeH = 768
myText = (c) by Rolf Mueller
fontName = serif
fontSize = 32
textWidth = 293
textHeight = 31
textAscent = 30
textDescent = 6
offset = 7
textXPos = 724
textYPos = 730
java.lang.ArrayIndexOutOfBoundsException: Coordinate out of bounds!
at sun.awt.image.IntegerInterleavedRaster.getDataElements(IntegerInterleavedRaster.java:202)
at java.awt.image.BufferedImage.getRGB(BufferedImage.java:862)
at ThumbnailGenerationTestX.doThumbnailGenerationTest(ThumbnailGenerationTestX.java:94)
at ThumbnailGenerationTestX.main(ThumbnailGenerationTestX.java:29)
The same piece of code running on Windows (win2k) gives me the following result:
sizeW = 1024
sizeH = 768
myText = (c) by Rolf Mueller
fontName = serif
fontSize = 32
textWidth = 260
textHeight = 28
textAscent = 32
textDescent = 7
offset = 7
textXPos = 757
textYPos = 733
Finished successfully!
I know, the environment on a Linux system is different, and I played around with
the fontsize a bit.
Is this a java/awt bug?
Or even a java/awt implementation bug on Fedora Core 2?
Or am I doing something wrong here?
Thanks for your help.
Any feedback appreciated.
Rolf