Java AffineTransform makes drawString disappear - java

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

Java Image, after scaled get black color, how to make it white?

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);

Java Graphics.drawLine() inexact: drawn lines are too long

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.

Writing String into a image in java

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);

Customize icon in Drag Drop Event?

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.

How do I turn off text antialiasing in this Java function?

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);

Categories

Resources