Wrapping/Rotating text on a image using graphics2D - java

void multiLine (int x, int y, String label, Graphics2D g) {
AffineTransform fontAT = new AffineTransform();
Font theFont = g.getFont();
fontAT.rotate(-Math.PI / 2);
Font theDerivedFont = theFont.deriveFont(fontAT);
g.setFont(theDerivedFont);
AttributedString attrStr = new AttributedString(label);
// Get iterator for string:
AttributedCharacterIterator characterIterator = attrStr.getIterator();
// Get font context from graphics:
FontRenderContext fontRenderContext = g.getFontRenderContext();
// Create measurer:
LineBreakMeasurer measurer = new LineBreakMeasurer(characterIterator,
fontRenderContext);
while (measurer.getPosition() < characterIterator.getEndIndex()) {
TextLayout textLayout = measurer.nextLayout(200);
y += textLayout.getAscent(); //Have tried changing y to x
textLayout.draw(g, x, y);
y += textLayout.getDescent() + textLayout.getLeading(); //Have tried changing y to x
}
g.setFont(theFont);
}
I am expecting this to print lines vertically but it does not , any ideas about how can I resolve this.
This outputs texts horizontally wrapped.
Edit: Changed the question to correctly reflect what I am trying to achieve

Reduce your wrapping width. 200 is too large, so it is not wrapping. Set it to 0, if you want each character on a new line.
TextLayout textLayout = measurer.nextLayout(0);

Related

Text doesnot rotate Graphics2D

I checked on site and followed all examples.
I have written the code, the position, font of text changes but the angle or rotation doesnt take place. Any help advice pointers are much appreciated
int x = X;
int y = Y;
int w = 9;
int h = 9;
int fontsize = 7;
Rectangle bounds = new java.awt.Rectangle(x, y, w, h);
ShapeGroup group = new ShapeGroup();
group.setAnchor(bounds);
slide.addShape(group);
Graphics2D graphics = new PPGraphics2D(group);
AffineTransform affineTransform = new AffineTransform();
affineTransform.rotate(50);
java.awt.Shape circle = new Ellipse2D.Float(x, y, 9, 9);
graphics.draw(circle);
graphics.setPaint(colorRating);
graphics.fill(circle);
//graphics.rotate(-Math.PI/2);
graphics.setColor(new Color(159, 78, 15));
Font font = new Font("Arial", Font.BOLD, fontsize);
Font rotatedFont = font.deriveFont(affineTransform);
graphics.setFont(rotatedFont);
graphics.setTransform(affineTransform);
graphics.drawString(siteName, x + 11, y + fontsize + 1);
graphics.setFont(font);
I reported a similar bug to vldocking project: when used on MacOS, tab titles didn’t rotate 90° when the tabs were on the left/right. After investigating further, I submitted a patch, which amounted to one line:
graphics.setRenderingHint(
RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
Without antialiasing, the text rendering took an optimized path, which skipped the ability to rotate the glyphs.
I don’t know if you are on a MacOS, with the same java implementation. Try setting the antialiasing attribute, and if that doesn’t work, some other rendering hints as well.
Good luck!

Changing font while drawing paragraph in Java

I am rendering a paragraph and, for word wrapping, I am using the LineBreakMeasurer and the TextLayout class.
This is the snippet that I am using , which is easily available online :
void drawParagraph(Graphics2D g, String paragraph, float width) {
LineBreakMeasurer linebreaker = new LineBreakMeasurer(new AttributedString(paragraph)
.getIterator(), g.getFontRenderContext());
int y = 0;
while (linebreaker.getPosition() < paragraph.length()) {
TextLayout textLayout = linebreaker.nextLayout(width);
y += textLayout.getAscent();
textLayout.draw(g, 0, y);
y += textLayout.getDescent() + textLayout.getLeading();
}
}
However, I am facing a problem, when I am trying to change the font.
Although i am changing the font by invoking g.setFont(new Font(...)), the paragraph is not being rendered in that font. However, when I try to use g.drawString(), it is working as expected.
Please help me with this problem.Thank you in advance.
Set the fonts in your AttributedString. For instance:
AttributedString text = new AttributedString(paragraph);
Font emphasis = new Font(Font.SERIF, Font.BOLD, 12);
int emphasisStart = 30;
int emphasisEnd = 42;
text.addAttribute(TextAttribute.FONT, emphasis, emphasisStart, emphasisEnd);
LineBreakMeasurer linebreaker =
new LineBreakMeasurer(text.getIterator(), g.getFontRenderContext());

How to zoom a buffered image?

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

Rotate Buffered Image (diagonal Text)

(Sorry for the links, I'm new and I cannot post images)
I want to accomplish the following : create a table with the legends on the top, and in a diagonal way.
but I'm having some problems, I have the following image, and I'm trying to rotate it 45º (the result it's at the right),
Here is my code:
//just some labels
ArrayList<String> labels = new ArrayList<String>();
labels.add("Juan");
labels.add("QWERTYYY");
labels.add("ANA");
// margin
int margin=3;
//diagonal = 45º
// value to shift each label
int diagonalShift = (int)(cellSizeWidth / Math.sqrt(2d));
// height, width represent the size of the final image
// heightSub, widthSub represent the size of the image to be rotated taking into account the shift for each label
int widthSub = height + (diagonalShift * labels.size());
int heightSub = width;
// image to Display
BufferedImage image = new BufferedImage(height, width, BufferedImage.TYPE_INT_RGB);
Graphics2D imageGraphics = (Graphics2D) image.getGraphics();
// tempImage: subImage to rotate and place in image
BufferedImage tempImage = new BufferedImage(widthSub, heightSub, BufferedImage.TYPE_INT_RGB);
Graphics2D tempImageGraphics = (Graphics2D) tempImage.getGraphics();
tempImageGraphics.setColor(Color.BLUE);
tempImageGraphics.drawRect(0, 0, widthSub-1, heightSub-1);
// I'd like to use antialias, but it's giving bad results
// tempImageGraphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
// drawing labels
// as we're designing a table cellSizeWidth and CellSizeHeight represent the dimensions for each cell
tempImageGraphics.setColor(Color.WHITE);
for (int i = 0; i < labels.size(); i++) {
String label = labels.get(i);
tempImageGraphics.drawString(label,
margin + (i * diagonalShift),
(int) (i * cellSizeWidth) + fontSize + centerDistance);
}
I tried the following:
//rotating
AffineTransform fontAfineTransform = new AffineTransform();
// fontAfineTransform.rotate(verticalTextDirection.rotationAngle());
which gives as result the image at the right in the second Image 2
so I need to apply a translation to get it to the right position
// Math.sqrt(2d) because I'm working with 45º and the height becomes the hypotenuse
// fontAfineTransform.translate(-height/Math.sqrt(2d),height/Math.sqrt(2d));
//drawing into image
imageGraphics.drawImage(tempImage, fontAfineTransform, null);
can someone please explain how the affineTransform works, or how can I get the text to be in a diagonal way.
Thanks

Cannot get right height of text in java.awt.BufferdImage/Graphics2D

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

Categories