how can I get Font X offset width in java2D? - java

I need print two words: "A" and "B" using java 2D
font size = 100;
"A" font family: Bodoni MT Poster Compressed
"B" font family: Arial
I writed below codes to do it:
BufferedImage image = new BufferedImage(400, 300, BufferedImage.TYPE_INT_RGB);
Graphics g = image.getGraphics();
{//fill bg color
g.setColor(new Color(255,255,255));
g.fillRect(0, 0, image.getWidth(), image.getHeight());
}
int FONT_SIZE=100;//set font size
{//print A
g.setColor(new Color(0,0,0));
g.setFont(new Font("Bodoni MT Poster Compressed", Font.PLAIN ,FONT_SIZE));
g.drawString("A",0,FONT_SIZE);
}
{//print B
g.setColor(new Color(0,0,0));
g.setFont(new Font("Arial", Font.PLAIN ,FONT_SIZE));
g.drawString("B",FONT_SIZE,FONT_SIZE);
}
g.dispose();
I get the result image:
but I need like this (make by PhotoShop):
I think the question at g.drawString("B",FONT_SIZE,FONT_SIZE);
How can I get the font X offset width?
thanks for help :)

After you do the setFont, declare a variable like
FontMetrics fm = g.getFontMetrics();
int strA = fm.stringWidth("A"),
strB = fm.stringWidth("B"),
strH = fm.getHeight();
Now that you have all the dimensions of the letters, set their positions (px is distance from the left edge to the letter, py from the top to the baseline of the font)
int px = ..., py = ...
g.drawString ("A", px, py);
And similarly for "B". Hope that helps, - M.S.

Related

Any better way to draw string with outline in Java?

I need to draw white text with black outline on a Graphics object I get from an image. I first draw the same text 4 times (moved left or right by one pixel) with black color and then once with white color. However this won't work well if outline needs to be more than 1px wide, and really seems like a hack. Is there a better way to do this?
final BufferedImage image = ImageIO.read(new File("./test.jpg"));
Graphics g = image.getGraphics();
g.setFont(g.getFont().deriveFont(45F));
// coordinates
int x = 100;
int y = 100;
String text = "Hello world";
g.setColor(Color.black);
g.drawString(text, x + 1, y - 1);
g.drawString(text, x + 1, y + 1);
g.drawString(text, x - 1, y - 1);
g.drawString(text, x - 1, y + 1);
g.setColor(Color.white);
g.drawString(text, x, y);
screenshot: https://i.imgur.com/ONLsPxy.png
The other option is to use below piece of code of creating a shape and then first drawing outline and then fill it:
Graphics2D g2d = (Graphics2D)g;
AffineTransform transform = g2d.getTransform();
transform.translate(x, y);
g2d.transform(transform);
g2d.setColor(Color.black);
FontRenderContext frc = g2d.getFontRenderContext();
TextLayout tl = new TextLayout(text, g.getFont().deriveFont(45F), frc);
Shape shape = tl.getOutline(null);
g2d.setStroke(new BasicStroke(5f));
g2d.draw(shape);
g2d.setColor(Color.white);
g2d.fill(shape);
Output:

Java calculate image center return minus negative results

I am trying to calculate image center(to add water marks)following - add-water-to-image and the results shows negative x, for some of the images, here is the math part:
int centerX = (sourceImage.getWidth() - (int) rect.getWidth()) / 2;
int centerY = sourceImage.getHeight() / 2;
and the entire function:
public void addTextWatermark(String text, File sourceImageFile, File destImageFile, int textSize) {
try {
BufferedImage sourceImage = ImageIO.read(sourceImageFile);
Graphics2D g2d = (Graphics2D) sourceImage.getGraphics();
// initializes necessary graphic properties
AlphaComposite alphaChannel = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.1f);
g2d.setComposite(alphaChannel);
g2d.setColor(Color.BLACK.darker());
//Font(fontName, fontStyle, foneSize)
g2d.setFont(new java.awt.Font("Arial", Font.BOLD, textSize));
FontMetrics fontMetrics = g2d.getFontMetrics();
//text - input text , g2d - Graphics2D
Rectangle2D rect = fontMetrics.getStringBounds(text, g2d);
// calculates the coordinate where the String is painted
int centerX = (sourceImage.getWidth() - (int) rect.getWidth()) / 2;
int centerY = sourceImage.getHeight() / 2;
// paints the textual watermark
g2d.drawString(text, centerX, centerY);
ImageIO.write(sourceImage, "png", destImageFile);
g2d.dispose();
} catch (IOException ex) {
System.out.println(ex.getMessage().toString());
}
}
1-Is there a way to ensure the math will work for all images?
2-Is there a diffrence between jpg and png in this calclation?
Thanks.
edit
The image sizes that was causeing it were:
1-to big(3000*3000).
2-to small(60*60).
With textSize(g2d.setFont(new java.awt.Font("Arial", Font.BOLD, textSize));) - 32 or less.
So I found 2 ways to handle this issue:
1- if x or y are smaller then 0 I have resize the image using resize-image
2- if the watermark is to small just increase text size - g2d.setFont(new java.awt.Font("Arial", Font.BOLD, textSize));
Thanks for all the help #jon Skeet.

How to fit font into pixel size in Java? How to convert pixels to points?

I need to create font of a givens size in pixels.
Java's Font class constructor requires font size expressed in points. Points are physical length while pixels are digitizes. So I need dpi.
It is said in manual, that this value is contained inside FontRenderContext.getTransform().
I found, that in my case, scaling is one, i.e. pixels = points.
Unfortunately, creating font of size 100 creates bigger image.
For example, code below
BufferedImage ans = new BufferedImage(width, height, imageType);
Font font = new Font(fontName,fontStyle,height);
Graphics2D g2 = ans.createGraphics();
g2.setFont(font);
FontMetrics fm = g2.getFontMetrics();
FontRenderContext frc = g2.getFontRenderContext();
System.out.println("height=" + height);
System.out.println("frc.getTransform()=" +frc.getTransform());
System.out.println("g2.getTransform()=" +g2.getTransform());
System.out.println("fm.getAscent()+fm.getDescent()="+fm.getAscent()+"+"+fm.getDescent()+"="+(fm.getAscent()+fm.getDescent()));
g2.drawString(str, 0, fm.getAscent());
gives
height=100
frc.getTransform()=AffineTransform[[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]]
g2.getTransform()=AffineTransform[[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]]
fm.getAscent()+fm.getDescent()=93+20=113
How to fit?
I've used this code to determine the size of a String in pixels when drawing the String.
The x and y calculation centers the String in the drawing area. The y calculation looks odd because the y origin is at the bottom left, not the top left.
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (font == null) {
return;
}
Graphics2D g2d = (Graphics2D) g;
FontRenderContext frc = g2d.getFontRenderContext();
TextLayout layout = new TextLayout(sampleString, font, frc);
Rectangle2D bounds = layout.getBounds();
int width = (int) Math.round(bounds.getWidth());
int height = (int) Math.round(bounds.getHeight());
int x = (getWidth() - width) / 2;
int y = height + (getHeight() - height) / 2;
layout.draw(g2d, (float) x, (float) y);
}
// using javafx: https://docs.oracle.com/javase/8/javafx/api/javafx/scene/text/package-summary.html
Text text = new Text("Hello World");
Font font = Font.font("Arial", 10); // 10 is point size
text.setFont(font);
double width = text.getLayoutBounds().getWidth(); // width is pixel size

Java parsing truetype font to extract each characters as image & its code

Is there any java library that can be used to extract each character from a true type font (.ttf)?
Each character of the font, I want to:
Convert it to the image
Extract its code (ex: Unicode value)
Anyone can help to show me some tips on above purpose?
P.S: I want to figure out, how such this app made: http://www.softpedia.com/progScreenshots/CharMap-Screenshot-94863.html
This will convert a String to a BufferedImage:
public BufferedImage stringToBufferedImage(String s) {
//First, we have to calculate the string's width and height
BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_4BYTE_ABGR);
Graphics g = img.getGraphics();
//Set the font to be used when drawing the string
Font f = new Font("Tahoma", Font.PLAIN, 48);
g.setFont(f);
//Get the string visual bounds
FontRenderContext frc = g.getFontMetrics().getFontRenderContext();
Rectangle2D rect = f.getStringBounds(s, frc);
//Release resources
g.dispose();
//Then, we have to draw the string on the final image
//Create a new image where to print the character
img = new BufferedImage((int) Math.ceil(rect.getWidth()), (int) Math.ceil(rect.getHeight()), BufferedImage.TYPE_4BYTE_ABGR);
g = img.getGraphics();
g.setColor(Color.black); //Otherwise the text would be white
g.setFont(f);
//Calculate x and y for that string
FontMetrics fm = g.getFontMetrics();
int x = 0;
int y = fm.getAscent(); //getAscent() = baseline
g.drawString(s, x, y);
//Release resources
g.dispose();
//Return the image
return img;
}
I think there isn't a way to get all the characters, you have to create a String or a char array where you store all the chars you want to convert to image.
Once you have the String or char[] with all keys you want to convert, you can easily iterate over it and convert call the stringToBufferedImage method, then you can do
int charCode = (int) charactersMap.charAt(counter);
if charactersMap is a String, or
int charCode = (int) charactersMap[counter];
if charactersMap is a char array
Hope this helps

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.

Categories

Resources