I use drawString by Font1, suppose deriveFont is 20f.
final int width = fontMetrics.stringWidth(text);
final int height = fontMetrics.getHeight();
BufferedImage rendered = new BufferedImage(
width, height, BufferedImage.TYPE_INT_ARGB
);
System.out.println("render:" + width + "," + height);
final Graphics2D gOfRendered = (Graphics2D) rendered.getGraphics();
gOfRendered.setRenderingHints(getRenderingHints());
gOfRendered.setColor(fontColor);
gOfRendered.setFont(fontMetrics.getFont());
gOfRendered.drawString(
text, 0, height - fontMetrics.getMaxDescent() - fontMetrics.getLeading()
);
result:
But when I scale font size(scale=4 result maybe normal,scale=8 will cause error result):
final Font font = (wordFrequency.hasFont() ? wordFrequency.getFont() : kumoFont).getFont().deriveFont(fontHeight * 1.0f);
final Font font2 = (wordFrequency.hasFont() ? wordFrequency.getFont() : kumoFont).getFont().deriveFont(fontHeight * scale * 1.0f);
final FontMetrics fontMetrics = graphics.getFontMetrics(font);
final FontMetrics fontMetrics2 = graphics.getFontMetrics(font2);
and render again:
final int width = fontMetrics2.stringWidth(text);
final int height = fontMetrics2.getHeight();
BufferedImage rendered = new BufferedImage(
width, height, BufferedImage.TYPE_INT_ARGB
);
final Graphics2D gOfRendered = (Graphics2D) rendered.getGraphics();
// set the rendering hint here to ensure the font metrics are correct
gOfRendered.setRenderingHints(getRenderingHints());
gOfRendered.setColor(fontColor);
gOfRendered.setFont(fontMetrics2.getFont());
gOfRendered.drawString(
text, 0, height - fontMetrics2.getMaxDescent() - fontMetrics2.getLeading()
);
Error result(scale=8):
I find final int width = fontMetrics2.stringWidth(text); is not 8 times the font width,the Numbers are very different,How to fix it?Thank you!
Related
I try to join two images. But not able to create it.
I am not able to understand what is the problem in the below code.
It is not able to create the concat.jpg file.
BufferedImage image = ImageIO.read(mainFile);
BufferedImage image1 = ImageIO.read(fileToMerge);
int width = Math.max(image.getWidth() , image1.getWidth());
int height = Math.max(image.getHeight() , image1.getHeight());
log.info("width {}", width);
log.info("height {}", height);
BufferedImage concatImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D graphics2D = concatImage.createGraphics();
graphics2D.drawImage(image, 0, image.getHeight(), null);
graphics2D.drawImage(image1, 0 , image1.getHeight(), null);
ImageIO.write(concatImage, "jpg", new File(Constants.LOCAL_FOLDER + "/concat.jpg"));
You want the height of concatImage to be the combined height of image and image1.
You want to draw image at coordinates (0,0) and you want to draw image1 at x = 0 and y = height of image
Try the following.
BufferedImage image = ImageIO.read(mainFile);
BufferedImage image1 = ImageIO.read(fileToMerge);
int width = Math.max(image.getWidth() , image1.getWidth());
int height = image.getHeight() + image1.getHeight();
log.info("width {}", width);
log.info("height {}", height);
BufferedImage concatImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D graphics2D = concatImage.createGraphics();
graphics2D.drawImage(image, 0, 0, null);
graphics2D.drawImage(image1, 0, image.getHeight(), null);
ImageIO.write(concatImage, "jpg", new File(Constants.LOCAL_FOLDER + "/concat.jpg"));
Note that you should call graphics2D.dispose() when you no longer need to use it.
I am trying to create a Plagiarism checker software. Till now I have created a buffered Image which converts any text written in an text area into a png,jpg,jpeg, gif format.
When I open the image text written inside the image is shown too small and it is shown properly only when I manually zoom my screen from keyboard or Mouse.
I have tried several techniques to zoom out or reposition the image but failed. How could I achieve a zoomed in image?
Here is my Code.
String text = textArea.getText();
Font font = new Font("Tahoma", Font.PLAIN, 40);
FontRenderContext frc = new FontRenderContext(null, true, true);
//get the height and width of the text
Rectangle2D bounds = font.getStringBounds(text, frc);
int w = (int) bounds.getWidth();
int h = (int) bounds.getHeight();
String[] parts = text.split("\n");
//create a BufferedImage object
BufferedImage img = new BufferedImage(w, h * parts.length, BufferedImage.TYPE_INT_RGB);
//calling createGraphics() to get the Graphics2D
Graphics2D g = img.createGraphics();
//set color and other parameters
g.setColor(Color.WHITE);
g.setFont(font);
int index = 0;
for(String part : parts){
g.drawString(part, 4000, h * index++);
}
g.dispose();
I just want to ask how to get the width and height of an image, because this returns -1 for width and height:
private void resizeImage(Image image){
JLabel imageLabel = new JLabel();
int imageWidth = image.getWidth(null);
int imageHeight = image.getHeight(null);
System.out.println("Width:" + imageWidth);
System.out.println("Height:" + imageHeight);
}
You should do something like this :
BufferedImage bimg = ImageIO.read(new File(filename));
int width = bimg.getWidth();
int height = bimg.getHeight();
as this post says
With Apache Commons Imaging, you can get image width and height with better performance, without reading entire image to memory.
Sample code below is using Sanselan 0.97-incubator (Commons Imaging is still SNAPSHOT as I write this):
final ImageInfo imageInfo = Sanselan.getImageInfo(imageData);
int imgWidth = imageInfo.getWidth();
int imgHeight = imageInfo.getHeight();
Exactly why this happens in your case is unclear, you don't specify exactly what image actually is.
Anyway, the answer can be found in the JavaDoc:
public abstract int getWidth(ImageObserver observer)
Determines the width of the image. If the width is not yet known, this method returns -1 and the specified ImageObserver object is notified later.
The width and height obiously cannot be immediately determined for the image in question. You need to pass an ImageObserver instance which will have this method called when height and width can be resolved.
public static BufferedImage resize(final Image image, final int width, final int height){
assert image != null;
final BufferedImage bi = new BufferedImage(width, height, image instanceof BufferedImage ? ((BufferedImage)image).getType() : BufferedImage.TYPE_INT_ARGB);
final Graphics2D g = bi.createGraphics();
g.drawImage(image, 0, 0, width, height, null);
g.dispose();
return bi;
}
The code posted above is one way of resizing an image. Generally to get the width and height of an image, you may do:
image.getWidth(null);
image.getHeight(null);
This is all under the assumption that the image is not null.
As seen below, I have a BufferedImage over another BufferedImage. They are both pngs and I would like there to be no background on the overlayed image. I'm sure there's so way to do this, but am unsure of where in the api.
Here's the method in question:
private static BufferedImage finalizeImage(BufferedImage originalImage, String tokenImage, Integer occurrences, int height, int width, int type){
//Font font = new Font("Courier New", Font.PLAIN, 12);
BufferedImage resizedImage = new BufferedImage(width, height, type);
Graphics2D g = resizedImage.createGraphics();
FontMetrics fm = g.getFontMetrics();
int strWidth = (fm.stringWidth(tokenImage));
int imageWidth = resizedImage.getWidth();
int textBegin = (imageWidth - strWidth) / 2;
//g.setFont(font);
g.drawImage(originalImage, 0, 0, width, height, null);
g.setColor(Color.black);
int textHeight = (fm.getAscent() + (TOKEN_HEIGHT - (fm.getAscent() + fm.getDescent())) / 2);
g.drawString(tokenImage, textBegin, textHeight);
//for multiple occurrences
try {
BufferedImage numOnSubscript = ImageIO.read(Thread.currentThread().getContextClassLoader().getResourceAsStream("images/ui/tokens/subscript.fw.png"));
g.drawImage(numOnSubscript, width - 20, height-20, 20, 20, null);
g.setColor(Color.white);
g.drawString(occurrences.toString(), width - 16, (height-20)*2 - 1);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
g.dispose();
return resizedImage;
}
Here is what is happening.
I found my problem. Of course, it's the silliest thing. I had a white background on as default in fireworks :-/
Im creating a servlet that renders a jpg/png with a given text. I want the text to be centered on the rendered image. I can get the width, but the height i'm getting seems to be wrong
Font myfont = new Font(Font.SANS_SERIF, Font.BOLD, 400);
BufferedImage image = new BufferedImage(500, 500, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = image.createGraphics();
g.setFont(myfont);
g.setColor(Color.BLACK);
FontMetrics fm = g.getFontMetrics();
Integer textwidth = fm.stringWidth(imagetext);
Integer textheight = fm.getHeight();
FontRenderContext fr = g.getFontRenderContext();
LineMetrics lm = myfont.getLineMetrics("5", fr );
float ascent = lm.getAscent();
float descent = lm.getDescent();
float height = lm.getHeight();
g.drawString("5", ((imagewidth - textwidth) / 2) , y?);
g.dispose();
ImageIO.write(image, "png", outputstream);
These are the values I get:
textwidth = 222
textheight = 504
ascent = 402
descent = 87
height = 503
Anyone know how to get the exact height om the "5" ? The estimated height should be around 250
It's still a bit off, but much closer (288): ask the Glyph (the actual graphical representation)
GlyphVector gv = myfont.createGlyphVector(fr, "5");
Rectangle2D bounds = gv.getGlyphMetrics(0).getBounds2D();
float height = bounds.height();
Other Glyph methods (getGlyphVisualBounds, getGlyphPixelBounds, ...) return the same value. This is the region of the affected pixels when the glyph is drawn, so you won't get a better value IMO
FontRenderContext frc = gc.getFontRenderContext();
float textheight = (float) font.getStringBounds(comp.text, frc).getHeight();