I am looking for an easy way to render a String into a rectangular box within a JPG whereas line breaks should happen automatically for that text box.
Is this possible with Graphics2D ?
Rendering a string on a single line is easy, the following code snippet uses Antialiasing as well as a good JPG output compression quality:
BufferedImage img = ImageIO.read(new File(".../input.jpg"));
int width = img.getWidth();
int height = img.getHeight();
Color zgColor = new Color(0xAB,0x3C,0x2E);
Color grey = new Color(0xCC,0xCC,0xCC);
BufferedImage bufferedImage = new BufferedImage(width, height, img.getType());
Graphics2D g = bufferedImage.createGraphics();
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// draw graphics
g.drawImage(img, 0, 0, null);
g.setColor(zgColor);
int y = 900;
int x = 50;
g.setFont(new Font("Arial", Font.BOLD, 80));
g.drawString("Demo Text", x, y);
y+=80;
g.setColor(Color.WHITE);
g.setFont(new Font("Arial", Font.BOLD, 60));
g.drawString("Some other text a bit below", x, y);
y+=400;
g.setFont(new Font("Arial", Font.BOLD, 30));
g.setColor(Color.WHITE);
g.drawString("AND THIS WOULD BE THE TEXT I'D LIKE TO FIT INTO A BOX WITH AUTOMATIC LINE BREAKS", x, y);
g.dispose();
// Save as high quality JPEG
File targetFile = new File(".......result.jpg");
//ImageIO.write(bufferedImage, "jpg", targetFile); // this would give bad quality!
Iterator iter = ImageIO.getImageWritersByFormatName("jpeg");
ImageWriter writer = (ImageWriter)iter.next();
ImageWriteParam iwp = writer.getDefaultWriteParam();
iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
iwp.setCompressionQuality(1); // best quality
FileImageOutputStream output = new FileImageOutputStream(targetFile);
writer.setOutput(output);
IIOImage image = new IIOImage(bufferedImage, null, null);
writer.write(null, image, iwp);
writer.dispose();
System.out.println("Done.");
Check out LineBreakMeasurer. The API has some example code to get you started.
Or another approach is to create a JLabel with your image. Then you can add a JTextArea to the label and set the wrapping property on. Then the text will automatically wrap when you add the text area to the label. You will manually need to set the bounds of the text area within the label to control the placement of the text.
Related
I want to convert my picture from colored to Black and white which seems to be created from scratch.
Here is the code which i tried as described on the different post:
BufferedImage bi = ImageIO.read(new File("/Users/***/Documents/Photograph.jpg"));
ColorConvertOp op =
new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_GRAY), null);
ImageIO.write(bi, "PNG", new File("/Users/bng/Documents/rendered2.png"));
op.filter(bi, bi);
But still my image is not converted to the Black and white. Additionally, this code is increasing the rendered2.png image size to 10 folds.
Also, it would be great if i could find some Java 8 way of doing this.
Any suggestions?
Here is the code which worked for me:
BufferedImage input = ImageIO.read(new File("/Users/bng/Documents/Photograph.jpg"));
// Create a black-and-white image of the same size.
BufferedImage im = new BufferedImage(input.getWidth(), input.getHeight(), BufferedImage.TYPE_BYTE_BINARY);
// Get the graphics context for the black-and-white image.
Graphics2D g2d = im.createGraphics();
// Render the input image on it.
g2d.drawImage(input, 0, 0, null);
// Store the resulting image using the PNG format.
ImageIO.write(im, "PNG", new File("/Users/bng/Documents/rendered.png"));
It was BufferedImage.TYPE_BYTE_BINARY which provided me the exact solution.
Lokking for the Java 8 Version for above code.
You have to find RGB of the existing colors of the image you want to change it.
Fyi, you want to change it as white RGB value is (255,255,255) and for black RGB value is (0,0,0)
Following method easily do the color change if you apply correct way of your requirement
private BufferedImage changeColor(BufferedImage image, int srcColor, int replaceColor)
{
BufferedImage destImage = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D g = destImage.createGraphics();
g.drawImage(image, null, 0, 0);
g.dispose();
for (int width = 0; width < image.getWidth(); width++)
{
for (int height = 0; height < image.getHeight(); height++)
{
if (destImage.getRGB(width, height) == srcColor)
{
destImage.setRGB(width, height, replaceColor);
}
}
}
return destImage;
}
you have to use the ColorConvertOp in a proper way:
create Source image
apply filter
save dest
example:
BufferedImage src = ImageIO.read(new File("/Users/***/Documents/Photograph.jpg"));
ColorConvertOp op =
new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_GRAY), null);
BufferedImage dest = op.filter(src, null);
ImageIO.write(dest, "PNG", new File("/Users/bng/Documents/rendered2.png"));
src:
dest:
I want to render a string using java in a a bufferedImage. the problem is when i use a small font (for example: 8pt) i have bad quality images and the image resolution is 72dpi.
i want to have the best quality for images and if possible change the images resolution to 360dpi.
Noted that i want to generate a database of a language words with differents fonts, font sizes and font styles. and i used the standard java API (Graphics2D, Font, RenderingHints, FontMetrics,...) to generate images.
here is my code:
public static void main(String[] args) {
String text = "ⴰⴱⴱⵓⵥⵥⵍ";
String [] polices=polices();
for(int i=0;i<polices.length;i++){
BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_3BYTE_BGR);
Graphics2D g2d = img.createGraphics();
Font font = new Font(polices[i], Font.PLAIN, 8);
g2d.setFont(font);
FontMetrics fm = g2d.getFontMetrics();
int width = fm.stringWidth(text);
int height = fm.getHeight();
g2d.dispose();
img = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
g2d = img.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2d.setFont(font);
g2d.setBackground(Color.WHITE);
g2d.clearRect(0, 0, width, height);
fm = g2d.getFontMetrics();
g2d.setColor(Color.BLACK);
g2d.drawString(text, 0, fm.getAscent());
g2d.dispose();
try {
ImageIO.write(img, "png", new File("Text "+i+".png"));
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
I searched a lot for a solution vainly, if someone can help me i will be thankfull.
A solution that uses any externe libraries is welcome too.
An 8pt font at 72dpi is 8/72*360 = size 40 font at 360dpi - so set the font size to 40.
As to how to set the DPI for an image, see the question How to set DPI information in an image?
I'm using Java to create an image with text. I set the color of the background and fill it up. Then I place the text using LineBreakMeasurer. The problem is (As you can see in the attached image) the image background around the text is blurry (if you zoom on). This is a problem for me. Is it possible to fix that?
final BufferedImage image = new BufferedImage(600, 400, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = image.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2d.setColor(new Color(255,0,0));
g2d.fillRect (0, 0, image.getWidth(), image.getHeight());
...
AttributedString attributedString = getAttributedString(text, fontSize, new Color(1.0f,1.0f,1.0f,0.9f));
AttributedCharacterIterator characterIterator = attributedString
.getIterator();
FontRenderContext fontRenderContext = g2d.getFontRenderContext();
LineBreakMeasurer measurer = new LineBreakMeasurer(characterIterator,
fontRenderContext);
while (measurer.getPosition() < characterIterator.getEndIndex()) {
TextLayout textLayout = measurer.nextLayout(width);
int currentX = x + (int)(width - textLayout.getVisibleAdvance()) / 2;
y += textLayout.getAscent();
textLayout.draw(g2d, currentX, y);
}
If you're referring to the artifacts around the letters, the problem isn't with your painting code. It's the result of saving the image as a JPEG. Save it using a non-lossy format, like PNG. You could also try reducing the compression of the JPEG, but saving as a PNG is probably easier.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Problems with newline in Graphics2D.drawString
String eol =System.lineSeparator();
String sampleText =epcURNText +eol+studentName+eol+DelayComments+eol+ArrivalMethodComments+eol;
System.out.println(sampleText);
Font font = new Font("Tahoma", Font.PLAIN, 11);
FontRenderContext frc = new FontRenderContext(null, true, true);
//get the height and width of the text
Rectangle2D bounds = font.getStringBounds(sampleText, frc);
int w = (int) bounds.getWidth();
int h = (int) bounds.getHeight();
//create a BufferedImage object
BufferedImage image = new BufferedImage(w, h,
BufferedImage.TYPE_INT_RGB);
//calling createGraphics() to get the Graphics2D
Graphics2D g = image.createGraphics();
//set color and other parameters
g.setColor(Color.WHITE);
g.fillRect(0, 0, w, h);
g.setColor(Color.BLACK);
g.setFont(font);
g.drawString(sampleText, (float) bounds.getX(),
(float) -bounds.getY());
//releasing resources
g.dispose();
// define the format of print document
ByteArrayOutputStream os = new ByteArrayOutputStream();
ImageIO.write(image, "gif", os);
File f = new File("MyFile.jpg");
ImageIO.write(image, "JPEG", f);
Within the aforementioned code I am trying to print a string with newline characters within an image. However the newline character is omitted thus my text is presented within a single line? Does anybody have any idea on how to fix this?
Render the text in a JLabel with HTML formatting as shown the LabelRenderTest source in this answer.
It provides something better than line-breaks - the style for body width. Better in the sense that we do not need to manually calculate where to put line breaks for text (which also might be rendered in fonts that are not fixed width).
I am trying to draw characters from Wingding.ttf font with Java Graphics.DrawString. But resulting image contains only rectangle instead of char.
BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_4BYTE_ABGR);
Graphics graphics = image.getGraphics();
Font font = new Font("Wingdings", Font.PLAIN, 20);
graphics.setFont(font);
graphics.setColor(Color.BLACK);
graphics.drawString("\u00d8", 10, 10); // THREE-D TOP-LIGHTED RIGHTWARDS ARROWHEAD char
ImageIO.write(image, "PNG", new File(TEST_DATA_DIR + "bullet_char.png"));
How can I do this?
I dont think wingdings is one of the "standard" fonts
Font font = null;
try {
font=Font.createFont( Font.TRUETYPE_FONT,
new FileInputStream(new File("/pathto/WINGDINGS.TTF")) );
} catch(Exception e) {
System.out.println(e);
}
font=font.deriveFont(Font.PLAIN, 200);
graphics.setFont(font);
once you load the font (its always PLANE 1 pnt) you can the derive the style and size you want....
As similar questions has been answered here: Drawing exotic fonts in a java applet, you need to pass \uF0d8 instead of \u00d8.
graphics.drawString("\uF0d8", 10, 10);