This is super-weird. When I create a BufferedImage, and do not change the Graphics2D.transform(), then I can draw a line and text with no problem.
When I do set the transform (I am setting the user space to use EMUs instead of pixels), then I can draw the line using EMU coordinates, but I can't draw text.
code here:
public void testBitmaps2() throws Exception {
// no scaling
BufferedImage image = new BufferedImage(300, 300, BufferedImage.TYPE_INT_ARGB);
Graphics2D graphics = image.createGraphics();
graphics.setBackground(new Color(0x00FFFFFF, true));
graphics.clearRect(0, 0, 300, 300);
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
java.awt.Font javaFont = new java.awt.Font("Arial", java.awt.Font.PLAIN, 24);
graphics.setFont(javaFont);
graphics.setColor(Color.BLACK);
graphics.setStroke(new BasicStroke(1));
graphics.draw(new Line2D.Float(100, 150, 200, 150));
graphics.drawString("hi there", 100, 150);
ImageIO.write(image, "png", new File("c:/temp/", "no_scaling.png"));
// scaling
image = new BufferedImage(300, 300, BufferedImage.TYPE_INT_ARGB);
graphics = image.createGraphics();
// scale to use EMUs, assuming 300DPI image
AffineTransform scaleToEmus = AffineTransform.getScaleInstance(300f / 914400f, 300f / 914400f);
graphics.transform(scaleToEmus);
graphics.setBackground(new Color(0x00FFFFFF, true));
graphics.clearRect(0, 0, 914400, 914400);
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
javaFont = new java.awt.Font("Arial", java.awt.Font.PLAIN, 24);
graphics.setFont(javaFont);
graphics.setColor(Color.BLACK);
graphics.setStroke(new BasicStroke(914400 / 300));
graphics.draw(new Line2D.Float(914400 / 3, 914400 / 2, 914400 * 0.666f, 914400 / 2));
graphics.drawString("hi there", 914400 / 3, 914400 / 2);
ImageIO.write(image, "png", new File("c:/temp/", "scaling.png"));
}
Ok, the javadocs are wrong! The docs say:
size - the point size of the Font
However, you need to scale it up to match the transform scaling.
Related
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);
I have a polygon with the vertices (0,0), (100,0), (100,100), and (0,100).
I debugged the program and those are the exact lines that java is drawing.
Instead of drawing an exact square, some of the lines are a pixel too long:
http://gyazo.com/7418546c51c9a10fc690b18afcc96360.png
(The green circle is just me testing the centroid).
When I move the square out of the corner, you can see that the top left corner is the only corner that is exactly correct.
Why is this happening?
Right before drawLine, I wrote the lines to the console after they were converted to integer coordinates, and they were correct. So I can't see what could possibly be wrong except for the drawLine functions.
drawLine:
g.drawLine((int) line.getStart().getX(), (int) line.getStart().getY(),
(int) line.getEnd().getX(), (int) line.getEnd().getY());
The line has a start vector and an end vector. The vectors contain an x and y.
Even when doing this:
g.drawLine(0, 0, 100, 0);
g.drawLine(100, 0, 100, 100);
g.drawLine(100, 100, 0, 100);
g.drawLine(0, 100, 0, 0);
It still produces the same result.
This works though:
g.drawLine(0, 0, 100, 0);
g.drawLine(101, 0, 101, 100);
g.drawLine(100, 101, 0, 101);
g.drawLine(0, 100, 0, 0);
The example you provided is working:
BufferedImage bi = new BufferedImage(200, 200, BufferedImage.TYPE_INT_ARGB);
Graphics g = bi.getGraphics();
g.fillRect(0, 0, bi.getWidth(), bi.getHeight());
g.setColor(Color.red);
g.translate(50, 50);
g.drawLine(0, 0, 100, 0);
g.drawLine(100, 0, 100, 100);
g.drawLine(100, 100, 0, 100);
g.drawLine(0, 100, 0, 0);
JOptionPane.showMessageDialog(null, new ImageIcon(bi));
There is a bug https://bugs.openjdk.java.net/browse/JDK-8049901 that describes one possible issue.
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);
I am dragging and dropping the jTable cell from one jTable to another jTable.For Now it is showing me default drag drop icon.
I am using TransferHandler class to implement this.
I Override getDragImage(image) to put my customize image But it is not working.
This way i implemented my code Implementation
I tried this code into this method.
File newFile = new File("./dragImage.jpeg");
Font font = new Font("Tahoma", Font.PLAIN, 11);
FontRenderContext frc = new FontRenderContext(null, true, true);
Rectangle2D bounds = font.getStringBounds(l_value, frc);
int w = (int) bounds.getWidth();
int h = (int) bounds.getHeight();
BufferedImage image = new BufferedImage(10,10, BufferedImage.TYPE_INT_RGB);
Graphics2D g = image.createGraphics();
g.setColor(Color.WHITE);
g.fillRect(0, 0, 10, 10);
g.setColor(Color.BLACK);
g.setFont(font);
g.drawString(l_value, (float) bounds.getX(), (float) -bounds.getY());
g.dispose();
return image;
This code is working in my main method but here in this function it is not working.
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);