getVisualBounds() return a dimension with all 0 - java

The following code failed to read bounding rectangle of given korean text & font (NotoSansCJKKr-Regular.otf font), despite the fact that it works well on other Google fonts. What is the problem here anyway?
String text = "안녕하세요";
BufferedImage buf = new BufferedImage(1, 1 , BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = (Graphics2D)buf.getGraphics();
setRenderingHints(g2);
FontRenderContext frc = g2.getFontRenderContext();
GlyphVector glyph = g2.getFont().createGlyphVector(frc, text);
Rectangle rect = glyph.getVisualBounds().getBounds();
Result rect:
java.awt.Rectangle[x=0,y=0,width=0,height=0]

Related

Why is my text-to-image method returning a fully-black image?

I'm trying to make a method that converts a given String (and Font) into a BufferedImage. However, every time I run it, it returns a fully black image. The exact size of the image seems to be correct, but all pixels are perfectly black.
Here's the code:
static final GraphicsEnvironment GE;
static
{
GE = GraphicsEnvironment.getLocalGraphicsEnvironment();
}
public static BufferedImage textToImage(String text, Font font)
{
if (font == null)
font = Font.getFont("Courier New");
FontRenderContext frc = new FontRenderContext(new AffineTransform(), false, false);
Rectangle2D bounds = font.getStringBounds(text, frc);
BufferedImage bi = new BufferedImage(
(int)(bounds.getWidth() + .5),
(int)(bounds.getHeight() + .5),
BufferedImage.TYPE_BYTE_BINARY
);
Graphics2D g = GE.createGraphics(bi);
g.setFont(font);
g.drawString(text, 0, 0);
return bi;
}
Here's "Hello World" in the default JOptionPane font displayed as a JOptionPane's icon:
The simple solution would be to change the color...
g.setColor(Color.WHITE);
g.fillRect(0, 0, bi.getWidth(), bi.getHeight());
g.setColor(Color.BLACK);
g.setFont(font);
g.drawString(text, 0, 0);
g.dispose();
Text, generally, isn't rendered from the y position down, it draw's up AND down from the y position, so you'll need to use something like...
FontMetrics fm = g.getFontMetrics();
g.drawString(text, 0, fm.getAscent());
to get the text to appear correctly...
Also font = Font.getFont("Courier New"); isn't doing what you think it is, this won't return the font named "Courier New", but will instead attempt to load the font file called "Courier New".
Try using something like...
if (font == null) {
font = new Font("Courier New", Font.PLAIN, 12);
}
instead...
You might like to take a closer look at Working with Text APIs for more details

Generate thumbnail and fill empty space with color

Is it possible to implement the first example with Scalr?
My code is the following:
BufferedImage thumbnail = Scalr.resize(ImageIO.read(sourceFile), Scalr.Method.ULTRA_QUALITY, Scalr.Mode.FIT_TO_WIDTH,
width, height, Scalr.OP_ANTIALIAS);
ImageIO.write(thumbnail, destinationfile.getExtension(), destinationfile);
What I want is to receive the image like this:
where the blue bars are the space I want to fill with the color.
Thank you
Update: maybe it is possible to implement with Thumbnailator?
Just done! Perhaps it can help you!
public static BufferedImage resizeAndCrop(BufferedImage bufferedImage) throws IOException {
int himg = bufferedImage.getHeight();
int wimg = bufferedImage.getWidth();
double rateh = himg/dim;
double ratew = wimg/dim;
double rate = ratew;
if(rateh>ratew)
rate = rateh;
int dimhimg = (int) (himg/rate);
int dimwimg = (int) (wimg/rate);
double startw = dim/2 - dimwimg/2;
double starth = dim/2 - dimhimg/2;
BufferedImage tThumbImage = new BufferedImage( dim, dim, BufferedImage.TYPE_INT_RGB );
Graphics2D tGraphics2D = tThumbImage.createGraphics(); //create a graphics object to paint to
tGraphics2D.setBackground( Color.WHITE );
tGraphics2D.setPaint( Color.WHITE );
tGraphics2D.fillRect( 0, 0, dim, dim );
tGraphics2D.setRenderingHint( RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
tGraphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
tGraphics2D.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
tGraphics2D.drawImage( bufferedImage, (int)startw, (int)starth, dimwimg, dimhimg, null ); //draw the image scaled
File ff = new File(path + "jdata/tmp/prova.jpg");
ImageIO.write( tThumbImage, "JPG", ff); //write the image to a file
BufferedImage croppedContainMethod = ImageIO.read(ff);
return croppedContainMethod;
}
Nobody has idea so I will publish my solution...
I decided to continue to use Scalr (I didn't checked the Thumbnailator's last version but the previous ones failed on big pictures).
So first of all I call resize method, and then, if sizes of the new thumbnail are bigger then given ones I call crop method that crops a thumbnail by the center.. The code is the following:
BufferedImage thumbnail = Scalr.resize(sourceFile, Scalr.Method.ULTRA_QUALITY, Scalr.Mode.AUTOMATIC, destinationSize.width, destinationSize.height);
if (thumbnail.getWidth() > destinationSize.width)
thumbnail = Scalr.crop(thumbnail, (thumbnail.getWidth() - destinationSize.width) / 2, 0, destinationSize.width, destinationSize.height);
else if (thumbnail.getHeight() > destinationSize.height)
thumbnail = Scalr.crop(thumbnail, 0, (thumbnail.getHeight() - destinationSize.height) / 2, destinationSize.width, destinationSize.height);
It is not ideal, but at least it handles 'wide' images after generation of thumbnails

Font to Image in SWT

I want to draw single character with specified Font and transparent background to an SWT Image, later save it to file. I do it like this:
FontData fontData; // info about the font
char ch = 'a'; // character to draw
Display display = Display.getDefault();
TextLayout textLayout = new TextLayout(display);
textLayout.setAlignment(SWT.CENTER);
textLayout.setFont(font);
textLayout.setText("" + ch);
Rectangle r = textLayout.getBounds();
Image img = new Image(display, r.width, r.height);
GC gc = new GC(img);
textLayout.draw(gc, 0, 0);
The character is drawn but it gets white background.
I tried to solve it by setting transparentPixel to white color, this makes background transparent but character looks ugly.
I also tried to set alphaData of the Image with 0's (fully transparent) before drawing anything on it, but alphaData doesn't update after drawing anything on the Image, it stays transparent all the time.
How to draw character with transparent background on the Image?
Have u tried drawing to BufferedImage with TYPE_INT_ARGB?
Image fontImage= new BufferedImage(width,height,BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = fontImage.createGraphics();
//here u write ur code with g2d Graphics
g2d.drawImage(fontImage, 0, 0, null);
g2d.dispose();
You have to use an intermediary ImageData to enable transparency
TextLayout textLayout = new TextLayout(font.getDevice());
textLayout.setText(s);
textLayout.setFont(font);
Rectangle bounds = textLayout.getBounds();
PaletteData palette = new PaletteData(0xFF, 0xFF00, 0xFF0000);
ImageData imageData = new ImageData(bounds.width, bounds.height, 32, palette);
imageData.transparentPixel = palette.getPixel(font.getDevice().getSystemColor(SWT.COLOR_TRANSPARENT).getRGB());
for (int column = 0; column < imageData.width; column++) {
for (int line = 0; line < imageData.height; line++) {
imageData.setPixel(column, line, imageData.transparentPixel);
}
}
Image image = new Image(font.getDevice(), imageData);
GC gc = new GC(image);
textLayout.draw(gc, 0, 0);
return image;

Is there a way to set a default color for transparency when using ColorConvertOp in Java2D?

I'm converting an image with transparency in it into a Colorspace that doesn't have transparency. I'd like to set a background color for the transparent areas. Right now when I convert it any area that is transparent turns to black in the final image. Is there a way to do that while I'm converting between ColorSpaces? Here is my code I use to convert between color spaces:
public BufferedImage convertColorspace( BufferedImage source, int newType) {
BufferedImage destination = new BufferedImage( source.getWidth(), source.getHeight(), newType);
ColorConvertOp colorConvertOp = new ColorConvertOp(null);
colorConvertOp.filter(source, destination);
return destination;
}
// here is how its used
BufferedImage converted = convertColorspace(combinedImage, BufferedImage.TYPE_3BYTE_BGR);
I'm converting from BufferedImage.TYPE_4BYTE_ARGB to BufferedImage.TYPE_3BYTE_BGR.
How about:
BufferedImage temp = new BufferedImage(source.getWidth(), source.getHeight(),
BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = temp.createGraphics();
g2.setColor(Color.green);
g2.fillRect(0, 0, source.getWidth(), source.getHeight());
g2.drawImage(0, 0, source, null);
g2.dispose();
Then call colorConvertOp.filter with temp instead of source.

Passing JRAbstractSvgRenderer (JRRenderable) in fillReport

I'm passing a simple implementation of JRAbstractSvgRenderer (taken from the ireports pdf manual) as one of the parameters using JasperFillManager.fillReport.
public class CustomImageRenderer extends JRAbstractSvgRenderer {
#Override
public void render(Graphics2D g2d, Rectangle2D rect) throws JRException {
System.out.println("CustomImageRenderer.render");
// Save the Graphics2D affine transform
AffineTransform savedTrans = g2d.getTransform();
Font savedFont = g2d.getFont();
// Paint a nice background...
g2d.setPaint(new GradientPaint(0, 0, Color.ORANGE,
0, (int) rect.getHeight(), Color.PINK));
g2d.fillRect(0, 0, (int) rect.getWidth(), (int) rect.getHeight());
Font myfont = new Font("Arial Black", Font.PLAIN, 50);
g2d.setFont(myfont);
FontRenderContext frc = g2d.getFontRenderContext();
String text = new String("JasperReports!!!");
TextLayout textLayout = new TextLayout(text, myfont, frc);
Shape outline = textLayout.getOutline(null);
Rectangle r = outline.getBounds();
// Translate the graphic to center the text
g2d.translate(
(rect.getWidth() / 2) - (r.width / 2),
rect.getHeight() / 2 + (r.height / 2));
g2d.setColor(Color.BLACK);
g2d.draw(outline);
// Restore the Graphics2D affine transform
g2d.setFont(savedFont);
g2d.setTransform(savedTrans);
}
}
...
Map parameters = new HashMap();
parameters.put("IMAGEPARAM", new CustomImageRenderer());
...
JasperPrint jasperPrint = JasperFillManager.fillReport(path, parameters, conn);
I have linked an Image component in my report to this parameter but the image does not display. What am I missing here?
What I'd like to accomplish is to eventually pass an already created Java2D image to my report but I don't want pass it as a raster image.
I don't know JasperReports, but you can create an off-screen java.awt.Image easily:
private Image getImage(int h, int w) {
BufferedImage bi = new BufferedImage(h, w, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = bi.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
// your drawing code
g2d.dispose();
return bi;
}
As a handy way to preview a rendering, you can create a JComponent that displays the image, e.g.:
JLabel label = new JLabel(new ImageIcon(getImage(h, w)));
Addendum: You might also try to determine if your renderer is being invoked at all or if it is somehow rendering nothing. If the latter, you might simplify your rendering code to some bare minimum such as setting the color and filling rect.

Categories

Resources