I am trying to write a string into a image using ImageIo. But while writing a large string ,full string is not written into that image.
Here's my code:
File url=new File(imgUrl);
BufferedImage image = ImageIO.read(url);
Graphics g = image.getGraphics();
g.setPaintMode();
g.setFont(g.getFont().deriveFont(30f));
g.drawString(text, 100, 100);
g.dispose();
This code works fine for small strings.but when the width of the string exceeds the width of the image,then full string is not displayed on that image.
Any suggestions?
i have an old method try it
public BufferedImage stringToImage(String text, Font font, Color bgColor, Color fgColor) {
BufferedImage image = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = (Graphics2D) image.getGraphics();
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
FontRenderContext fc = g2d.getFontRenderContext();
Rectangle2D bounds = font.getStringBounds(text, fc);
//calculate the size of the text
int width = (int) bounds.getWidth();
int height = (int) bounds.getHeight();
image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
g2d = (Graphics2D) image.getGraphics();
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setFont(font);
g2d.setColor(bgColor);
g2d.fillRect(0, 0, width, height);
g2d.setColor(fgColor);
g2d.drawString(text, 0, (int)-bounds.getY());
g2d.dispose();
return image;
}
and use
BufferedImage image = stringToImage(text, font, bgColor, fgColor);
ImageIO.write(image, "jpg", file);
Not tested, but it could be done as this:
JLabel label = new JLabel("<html><h2>Title</h2><p>large text ...</p>");
int w = image.getWidth();
int h = image.getHeigth();
label.setBounds(0, 0, w, h);
SwingUtilities.paintComponent(g, label, null, 0, 0, w, h);
There are many ways to acheive this.
FontRenderContext/GlyphVector as mentioned by pbaris. See this answer for an e.g.
FontMetrics as seen in this answer.
A JLabel (possibly multi-line) to contain and size the text. As mentioned by Joop E.G. LabelRenderTest
You can use JTextArea to layout text:
JTextArea textArea = new JTextArea(text);
textArea.setFont(g.getFont().deriveFont(30f));
textArea.setOpaque(false);
textArea.setWrapStyleWord(true);
textArea.setLineWrap(true);
textArea.setBounds(0, 0, image.getWidth(), image.getHeight());
textArea.paint(g);
Related
I need to convert text to an Image. I found some code in an other thread which I modified a little bit.
Locally all is working fine. The text ends exactelly at the end of the image. But on the server (running openJDK) not the entire text is visible (2.5 letters are missing).
I tried to calculate the right width on different ways. e.g.
FontRenderContext frc = g2d.getFontRenderContext();
Rectangle2D r2d = font.getStringBounds(row, frc);
int width = (int)Math.ceil(r2d.getWidth());
int width = g2d.getFontMetrics(g2d.getFont()).stringWidth(row);
But the calculated width is allways the same.
public static BufferedImage text2Image(Font font, Color textColor, Color backgroundColor, String...textRows) {
BufferedImage helperImg = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = helperImg.createGraphics();
g2d.setFont(font);
FontMetrics fm = g2d.getFontMetrics();
int width = 0;
for(String row : textRows) {
if(fm.stringWidth(row) > width) {
width = fm.stringWidth(row);
}
}
int height = fm.getHeight() * textRows.length;
g2d.dispose();
BufferedImage finalImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
g2d = finalImg.createGraphics();
g2d.setColor(backgroundColor);
g2d.fillRect(0, 0, width, height);
g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
g2d.setFont(font);
fm = g2d.getFontMetrics();
g2d.setColor(textColor);
int y = fm.getAscent();
for(String row : textRows) {
g2d.drawString(row, 0, y);
y += fm.getHeight();
}
g2d.dispose();
return finalImg;
}
What is the best way to calculate the nessecary width that works platform independent? Thanks for your help.
#MadProgrammer
Thanks for the hint!
That it is. This two hints has to be set additionally before calculating the size.
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
i want to add additional space in images, lets call it "span".
My code is:
BufferedImage newImage = new BufferedImage(image2.getWidth(), image2.getHeight()+200, image2.getType());
Graphics g = newImage.getGraphics();
g.setColor(Color.white);
g.fillRect(0,0,image.getWidth(),image.getHeight()+100);
g.drawImage(image, 0, 100, null);
g.setColor(Color.white);
g.dispose();
RenderedImage rendImage = newImage;
String newUrl8006002 = splitUrl[0]+"-800x6002.jpg";
File file = new File(newUrl8006002);
ImageIO.write(rendImage, "jpg", file);
The problem is, that image at the bottom has black background and i expect white (at the top is white).
Do you know what to change to add white background in whole image?
How about this:
static BufferedImage growY(BufferedImage im, int span, Color color)
{
BufferedImage newImage = new BufferedImage(im.getWidth(), im.getHeight()+span, im.getType());
int topSpan = span/2;
int botSpan = span - topSpan;
Graphics g = newImage.getGraphics();
g.setColor(color);
g.fillRect(0, 0, newImage.getWidth(), topSpan);
g.fillRect(0, topSpan+im.getHeight(), newImage.getWidth(), botSpan);
g.drawImage(im, 0, topSpan, null);
g.dispose();
return newImage;
}
I try to scale image to 50x50 px, but I got black color. I need to make black to white
after scaled
this my code:
BufferedImage imgs = urlToBufferImage("src//imgTest.jpg");
BufferedImage resizedImage = new BufferedImage(50, 50, imgs.getType());
Graphics2D g = resizedImage.createGraphics();
// g.setBackground(Color.WHITE);
// g.drawImage(imgs, 0, 0, 50, 50,Color.WHITE, null);
g.drawImage(imgs.getScaledInstance(50, -1, Image.SCALE_DEFAULT), 0, 0, this);
g.dispose();
This is pretty simple.
My approach would be not to create a new BufferedImage, but to do:
BufferedImage imgs = urlToBufferImage("src//imgTest.jpg");
Graphics g = imgs.createGraphics();
g.drawImage(imgs, x, y, 50, 50, null);
or instead of drawing the image inside of the bounds, you could do
Graphics2D g2d = imgs.createGraphics();
g2d.scale(0.5, 0.5);
g2d.drawImage(imgs, x, y, null);
Basically I would like to turn off antialias in the following:
public BufferedImage createText(String text) {
//create image
BufferedImage image = new BufferedImage(95, 20,
BufferedImage.TYPE_INT_ARGB);
Graphics2D graphics = (Graphics2D) image.getGraphics();
//set background
graphics.setColor(Color.white);
graphics.fillRect(0, 0, 95, 20);
//draw text
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_OFF);
graphics.setColor(Color.black);
graphics.setFont(new Font("volter", Font.PLAIN, 9));
graphics.drawString(text, 0, 10);
return image;
}
but it's not working, here is something this function generates:
I just want black and white to be used, nothing else so it's important I get antialias disabled!
Try this instead:
graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
I've got a full-screen JFrame and I'd like to create an background for it by filling a JLabel with an image and matching it's size to the dimension of the screen.
Whilst I can create a JLabel that matches the screen's size I can't seem to resize my image to fit. In essence, I want to end up with a full-screen JFrame that is completely filled with an image (regardless of the image's or the screen's dimensions).
Current code is below, thanks!
public void addBackground(ImageIcon imgIcon) {
Image img = imgIcon.getImage();
BufferedImage buffImg = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB);
BufferedImage resizeBuffImg = resize(buffImg, screenSize.width, screenSize.height);
Image finalImg = Toolkit.getDefaultToolkit().createImage(resizeBuffImg.getSource());
ImageIcon back = new ImageIcon(finalImg);
System.out.println("IMAGE WIDTH: " + back.getIconWidth());
System.out.println("IMAGE HEIGHT: " + back.getIconHeight());
JLabel backgroundLabel = new JLabel(back);
getContentPane().add(backgroundLabel);
}
public BufferedImage resize(BufferedImage image, int width, int height) {
int type = image.getType() == 0? BufferedImage.TYPE_INT_ARGB : image.getType();
BufferedImage resizedImage = new BufferedImage(width, height, type);
Graphics2D g = resizedImage.createGraphics();
g.setComposite(AlphaComposite.Src);
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.setRenderingHint(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g.drawImage(image, 0, 0, width, height, null);
g.dispose();
return resizedImage;
}
EDIT - Got it! Using Image's getScaledInstance() works. It's not perfect, but I'm intending to scale down large images rather than expand smaller ones.