Write text on the screen with LWJGL - java

I want to write text on the screen for my game, for things like fps, random text for items and stuff. How can I write that text?
Is it possible without the Basic Game class? Isn't there a command like this g.drawString("Hello World", 100, 100);?

Update: this answer is now outdated, and does not work at all with the latest versions of LWJGL. Until I update this answer fully, I recommend that you look here: https://jvm-gaming.org/t/lwjgl-stb-bindings/54537
You could use the TrueType fonts feature in the Slick-util library.
Using a common font is easy, just create the font like this:
TrueTypeFont font;
Font awtFont = new Font("Times New Roman", Font.BOLD, 24); //name, style (PLAIN, BOLD, or ITALIC), size
font = new TrueTypeFont(awtFont, false); //base Font, anti-aliasing true/false
If you want to load the font from a .ttf file, it's a little more tricky:
try {
InputStream inputStream = ResourceLoader.getResourceAsStream("myfont.ttf");
Font awtFont = Font.createFont(Font.TRUETYPE_FONT, inputStream);
awtFont = awtFont.deriveFont(24f); // set font size
font = new TrueTypeFont(awtFont, false);
} catch (Exception e) {
e.printStackTrace();
}
After you have successfully created a TrueTypeFont, you can draw it like this:
font.drawString(100, 50, "ABC123", Color.yellow); //x, y, string to draw, color
For more information, you can look at the documentation for TrueTypeFont and java.awt.Font, and the Slick-Util tutorial I got most of this code from.

Try Making a BufferedImage of required size. Then get its Graphics and draw a String. Then Convert it to a ByteBuffer and render it in OpenGL.
String text = "ABCD";
int s = 256; //Take whatever size suits you.
BufferedImage b = new BufferedImage(s, s, BufferedImage.TYPE_4BYTE_ABGR);
Graphics2D g = b.createGraphics();
g.drawString(text, 0, 0);
int co = b.getColorModel().getNumComponents();
byte[] data = new byte[co * s * s];
b.getRaster().getDataElements(0, 0, s, s, data);
ByteBuffer pixels = BufferUtils.createByteBuffer(data.length);
pixels.put(data);
pixels.rewind();
Now pixels contains the required Image data you need to draw.
Use GL11.glTexImage2D() function to draw the byte buffer.

Related

I want to create an jpg image dynamically based on the text input using core java

I am trying to create images at runtime using graphics class. But though I have a string like line 1 \n line 2, I get the text written on the image as a single line.
Can anyone help me on this front with an example?
To remove the line breaks from your string, you can use the following method:
String str = "Line 1\nLine 2";
str.replace(System.getProperty("line.separator"), "");
You can use the BufferedImage class for creating the image:
// Create the target Font and a FontMetrics object for measuring the string's dimensions on the canvas
Font font = new Font("Helvetica", Font.PLAIN, 12);
FontMetrics fm = new Canvas().getFontMetrics(font);
// Create a BufferedImage and obtain the Graphics object
BufferedImage img = new BufferedImage(fm.stringWidth(str), fm.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics g = img.getGraphics();
// Draw the string at position (0|0)
g.setColor(Color.black);
g.drawString(str, 0, 0);

How to make a TIFF transparent in Java using JAI?

I'm trying to write a TIFF from a BufferedImage using Java Advanced Imaging (JAI), and am unsure of how to make it transparent. The following method works for making PNGs and GIFs transparent:
private static BufferedImage makeTransparent(BufferedImage image, int x, int y) {
ColorModel cm = image.getColorModel();
if (!(cm instanceof IndexColorModel)) {
return image;
}
IndexColorModel icm = (IndexColorModel) cm;
WritableRaster raster = image.getRaster();
int pixel = raster.getSample(x, y, 0);
// pixel is offset in ICM's palette
int size = icm.getMapSize();
byte[] reds = new byte[size];
byte[] greens = new byte[size];
byte[] blues = new byte[size];
icm.getReds(reds);
icm.getGreens(greens);
icm.getBlues(blues);
IndexColorModel icm2 = new IndexColorModel(8, size, reds, greens, blues, pixel);
return new BufferedImage(icm2, raster, image.isAlphaPremultiplied(), null);
}
But when writing a TIFF, the background is always white. Below is my code used for writing TIFF:
BufferedImage destination = new BufferedImage(sourceImage.getWidth(), sourceImage.getHeight(), BufferedImage.TYPE_BYTE_INDEXED);
Graphics imageGraphics = destination.getGraphics();
imageGraphics.drawImage(sourceImage, 0, 0, backgroundColor, null);
if (isTransparent) {
destination = makeTransparent(destination, 0, 0);
}
destination.createGraphics().drawImage(sourceImage, 0, 0, null);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageOutputStream ios = ImageIO.createImageOutputStream(baos);
TIFFImageWriter writer = new TIFFImageWriter(new TIFFImageWriterSpi());
writer.setOutput(ios);
writer.write(destination);
I also do some metadata manipulation later as I'm actually dealing with GeoTIFF. But still the images are white at this point. While debugging, I can view the BufferedImage and it is transparent, but when i write the image, the file has a white background. Do I need to do something specific with TiffImageWriteParam? Thanks for any help you can provide.
TIFF has no option of storing transparency info (alpha channel) in the palette (as in your IndexedColorModel). The palette only supports RGB triplets. Thus, the fact that you set a color index to transparent is lost when you write the image to a TIFF.
If you need a transparent TIFF, your options are:
Use normal RGBA instead of indexed color (RGB, 4 samples/pixel, unassociated alpha). Just use BufferedImage.TYPE_INT_ARGB or TYPE_4BYTE_ABGR, probably. This will make the output file bigger, but is easy to implement, and should be more compatible. Supported by almost all TIFF software.
Save a separate transparency mask (a 1 bit image with photometric interpretation set to 4) with the palette image. Not sure if it supported by much software, some may display the mask as a separate b/w image. Not sure how this can be achieved in JAI/ImageIO, might require writing a sequence and setting some extra metadata.
Store a custom field containing the transparent index. Will not be supported by anything but your own software, but the file will still be compatible and displayed with the white (solid) background in other software. You should be able to set this using the TIFF metadata.

JavaFX Canvas Fonts are all the same

I'm trying to write onto the JavaFX canvas. I'm having problems mixing my fonts. I'm using black and white.
Font currentFont = new Font("Georgia",125);
FontMetrics metrics = Toolkit.getToolkit().getFontLoader().getFontMetrics(currentFont);
canvas.getGraphicsContext2D().setFont(currentFont);
float charWidth = metrics.computeStringWidth(jString);
canvas.getGraphicsContext2D().fillText(jString, 1, 100, charWidth);
float charWidthSum = charWidth;
canvas.getGraphicsContext2D().setFont(new Font("Carlito",60));
metrics = Toolkit.getToolkit().getFontLoader().getFontMetrics(new Font("Carlito",60));
charWidth = metrics.computeStringWidth(aString);
canvas.getGraphicsContext2D().fillText(aString, charWidthSum, 100, charWidth);
charWidthSum+=charWidth;
canvas.getGraphicsContext2D().setFont(new Font("Ariel",50));
metrics = Toolkit.getToolkit().getFontLoader().getFontMetrics(new Font("Ariel",50));
charWidth = metrics.computeStringWidth(vString);
canvas.getGraphicsContext2D().fillText(vString, charWidthSum,100, charWidth);
charWidthSum+=charWidth;
canvas.getGraphicsContext2D().setFont(new Font("Times",125));
metrics = Toolkit.getToolkit().getFontLoader().getFontMetrics(new Font("Times",125));
charWidth = metrics.computeStringWidth(a2String);
canvas.getGraphicsContext2D().fillText(a2String, charWidthSum, 100, charWidth);
//HOW TO IMPLEMENT - to collect the content of a string, keeping font type the same
/*
public void setPixels(int x, int y, int w, int h,
PixelFormat<ByteBuffer> pixelformat,
byte buffer[], int offset, int scanlineStride);
*/
ByteBuffer byteBuffer = null;
byte[] bytes = new byte[0];
PixelFormat<ByteBuffer> pixelFormat = null;
canvas.getGraphicsContext2D().getPixelWriter().setPixels(0,0,0,0,null,bytes, 0,0); //write my new character
//
Will be same font, as I assume I'm just setting the current writeable font. If you see the unimplemented part, I'm considering trying to write the fonts using pixel writer. How to get them into the correct form? I'm using black monotone fonts
Also, I'm aware of TextFlow and StyledTextArea. StyledTextArea is for same height text, and TextFlow is not writable onto canvas, only onto a node. I need canvas functionality, I think.

IText - BarcodeQRCode making the background color transparent

I'm trying to set the background color of my QR Code using iText into a transparent background, however it does not work. Shows only white bars and black background.
What i have done so far:
My Code Snippet:
PdfContentByte cb = writer.getDirectContent();
BarcodeQRCode qrcode = new BarcodeQRCode("sample message on qr", 100, 100, null);
java.awt.Image qrImage = qrcode.createAwtImage(Color.WHITE,new Color(0, 0, 0, 0));
Image finalImage = Image.getInstance(writer, qrImage, 1);
finalImage.setAbsolutePosition(positionX, positionY);
cb.addImage(finalImage);
I have already generated my QR code and produced a PDF, however, when using
qrcode.createAwtImage(Color.WHITE,new Color(0, 0, 0, 0));
It does not produce an alpha background, instead it only shows a black background color.
I have also tried:
java.awt.Image qrImage =
qrcode.createAwtImage(Color.WHITE,Color.OPAQUE);
But obviously, my arguments are incorrect.
Help will be most appreciated, i've been working on this for a day now.
I have also tried Graphics, Graphics2g, converting it into BufferedImage.
Changing the assignment of finalImage to the following works:
Image finalImage = Image.getInstance(qrImage, null)
I don't know why using the getInstance method that takes a PdfWriter as first argument ruins the transparency, though...
I would solve this problem like this:
BarcodeQRCode qrcode = new BarcodeQRCode("sample message on qr", 100, 100, null);
Image image = qrcode.getImage();
Image mask = qrcode.getImage();
mask.makeMask();
image.setImageMask(mask);
document.add(image);
There may be an AWT solution too, but I'm more familiar with native PDF solutions than with using an AWT workaround.

How can I generate text image same as the JLabel label?

I would like to generate text image same as the JLabel label without displaying JLabel.
I tried same Font, same drawing method.
But generated image is not same as JLabel.
My sourcecode is below.
* 'super.paintComponent(g)' has been commented out for clarity that it is the same way. Output image is same.
* Below drawing by 'View.paint' method, but I'm tried 'SwingUtilities2.drawString' too. Two results are the same.
/* Label */
JLabel label = new JLabel(text) {
#Override
public void paintComponent(Graphics g) {
//super.paintComponent(g);
View v = BasicHTML.createHTMLView(this, getText());
v.paint(g, new Rectangle(0, 0, getWidth(), getFontMetrics(
getFont()).getAscent()));
}
};
label.setFont(new Font("Consolas", Font.PLAIN, 13));
/* Image */
FontMetrics fm = label.getFontMetrics(font);
BufferedImage image = new BufferedImage(fm.stringWidth(text),
fm.getHeight(), BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = image.createGraphics();
g2d.setFont(label.getFont());
// Clear background.
g2d.setPaint(label.getBackground());
g2d.fillRect(0, 0, image.getWidth(), image.getHeight());
// Draw string.
g2d.setClip(new Rectangle(0, 0, image.getWidth(), image.getHeight()));
View v = BasicHTML.createHTMLView(label, text);
v.paint(g2d, new Rectangle(0, 0, image.getWidth(),
g2d.getFontMetrics().getAscent()));
// ... output image to file ...
Result image is following.
[JLabel]
[Generated image]
Generated image is slightly thin-faced, as compared to JLabel's capture.
How can I generate text image same as the JLabel label?
Thank you for your consideration.
I'm not sure, but you might need to create a compatible buffered image (compatible to the display)
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gs = ge.getDefaultScreenDevice();
GraphicsConfiguration gc = gs.getDefaultConfiguration();
// Create an image that does not support transparency
BufferedImage bimage = gc.createCompatibleImage(100, 100, Transparency.OPAQUE);
This will at least get you on a close with the graphics been used to render to the screen
You might also like to pay around with the rendering quality as well
Kleopatra did a post on a similar question awhile ago, you might to try and hunt it down
Why do you use BasicHTML.createView if you want to have the same as JLabel?
You could use the JLabel directly (if you only want the text and not the background, set opaque to false and the border to null)
or you can use g2d.drawString()

Categories

Resources