How to increase Graphics2D text quality? - java

I have a question concerning printing additional information on barcodes. I am using http://barbecue.sourceforge.net/ to create my barcodes.
After I created my barcodes I want to add some additional information. At the moment i do this with the following way! For example:
Graphics2D g2d5 = container4Barcode.createGraphics();
g2d5.setBackground(Color.WHITE);
g2d5.clearRect(0, 33, 200, 200);
g2d5.setColor(Color.BLACK);
g2d5.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2d5.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
g2d5.setFont(new Font("Arial", Font.PLAIN, 8));
g2d5.drawString(barcode, 8, 40);
g2d5.drawString(generateRandomNumber(ekPreis), 57, 40);
String datumResult = datum;
g2d5.drawString(location, 98, 40);
g2d5.drawString(datum.substring(2), 114, 40);
g2d5.dispose();
The output is in a pdf the following:
As you can see is the quality of my text (above and under the barcode) is really bad ... How can I increase the quality of the text to make the text more smoother and not that pixelated?!
(When I print my barcodes, the barcodes look very pixelated ...)
Any tips?
UPDATE:
So, I added here the a picture of my latest outcome ... When I print out these barcodes they look horrible! So here is the code what I did:
Graphics2D g2d6 = container4Barcode.createGraphics();
g2d6.setColor(Color.black);
g2d6.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2d6.setFont(new Font("Verdana", Font.BOLD, 7));
g2d6.drawString("FLORETT", 9, 20);
g2d6.drawString("50-521-60", 57, 20);
Graphics2D g2d4 = container4Barcode.createGraphics();
g2d4.setColor(Color.black);
g2d4.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2d4.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
RenderingHints.VALUE_FRACTIONALMETRICS_ON);
g2d4.setFont(new Font("Verdana", Font.BOLD, 11));
g2d4.drawString("SSYYS", 105, 19);
g2d4.dispose();
With that Code I get the best results! Of course I played with "Metrics, AA_GASP, LCS_HRGB, different fonts (Verdana is the best in my opinion) ..." and a lot more, but some of them I couldn't use, because then my barcode got blurred! So actioally I am forcing the problem that I am unable to improve the quality of my text-quality of the drawstring from graphics2d!
So, I want to ask if there is a possibility to let the "SSYYS" (Font Size 11) and the "FLORETT" (Font Size 7) look much nicer! Is there a possibility in JAVA to draw "smooth" text on an image with a font size less than "12" ? Is there a workaround to to that ? As you can see in the picture the letters "S and Y" look very awful...
2nd Update:
Some Example code so far... Please be sure that the following folder exists: C:\TestBarcodes\
Hope I reduced my code to the minimum that you can imagine what my problem is...
package generator;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.FileOutputStream;
import java.io.IOException;
import net.sourceforge.barbecue.Barcode;
import net.sourceforge.barbecue.BarcodeException;
import net.sourceforge.barbecue.BarcodeFactory;
import net.sourceforge.barbecue.output.OutputException;
import org.apache.pdfbox.exceptions.COSVisitorException;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.edit.PDPageContentStream;
import org.apache.pdfbox.pdmodel.graphics.xobject.PDJpeg;
import org.apache.pdfbox.pdmodel.graphics.xobject.PDXObjectImage;
public class BarcodeGen {
// sets the picWidth
private static int picWidth = 149;
// sets the picHeigth
private static int picHeigth = 60;
public static void main(String[] args)
throws BarcodeException, OutputException, COSVisitorException, IOException {
generateBarcode("11138500");
}
public static void generateBarcode(String barcode)
throws IOException, COSVisitorException, BarcodeException, OutputException {
Barcode barcode2 = BarcodeFactory.createCode39(barcode, false);
int gw = barcode2.getWidth();
// change this to suit if you want higher, default 50
// barcode2.setBarWidth(50);
// this sets DPI
barcode2.setResolution(100);
// barcode2.setFont(font);
int gh = barcode2.getHeight();
// change this if you want a coloured background
// image = new BufferedImage(t, s, BufferedImage.TYPE_INT_RGB)
BufferedImage image = new BufferedImage(gw, gh, BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = (Graphics2D) image.getGraphics();
// default is black so draw a white box first
// change type to INT_RGB if you want a coloured background
g2.setColor(Color.white);
g2.fillRect(0, 0, gw, gh);
barcode2.draw(g2, 0, 0);
// CREATE ADDITIONAL INFORMATION ON BARCODE
BufferedImage container4Barcode = new BufferedImage(
picWidth, picHeigth, image.getType());
Graphics2D g2d = container4Barcode.createGraphics();
g2d.setBackground(Color.WHITE);
g2d.clearRect(0, 0, picWidth, picHeigth);
g2d.setColor(Color.black);
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
g2d.drawImage(image, 8, 21, 130, 18, null);
g2d.dispose();
Graphics2D g2d6 = container4Barcode.createGraphics();
g2d6.setColor(Color.black);
g2d6.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2d6.setFont(new Font("Verdana", Font.BOLD, 7));
g2d6.drawString("FLORETT", 9, 20);
g2d6.drawString("50-521-60", 57, 20);
Graphics2D g2d4 = container4Barcode.createGraphics();
g2d4.setColor(Color.black);
g2d4.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2d4.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
RenderingHints.VALUE_FRACTIONALMETRICS_ON);
g2d4.setFont(new Font("Verdana", Font.BOLD, 11));
g2d4.drawString("SSYYS", 105, 19);
g2d4.dispose();
// PRINT PDF
int ver = 782;
PDDocument doc = new PDDocument();
PDPage page = new PDPage(PDPage.PAGE_SIZE_A4);
doc.addPage(page);
PDXObjectImage image2 = new PDJpeg(doc, container4Barcode);
PDPageContentStream content = new PDPageContentStream(doc, page);
content.drawImage(image2, 5, ver);
content.close();
doc.save(new FileOutputStream("C:\\TestBarcodes\\barcode.pdf"));
// opens the pdf file
Process p = Runtime
.getRuntime()
.exec("rundll32 url.dll,FileProtocolHandler C:\\TestBarcodes\\barcode.pdf");
try {
p.waitFor();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

If someone wants to use pixel images in such cases, and not vector, then image should be upscaled for better printing quality:
static final int PIXELS_PER_POINT = 4; // 4x
Then define all dimensions in points, not in pixels:
// Image size in points
static final int IMAGE_WIDTH = 150;
static final int IMAGE_HEIGHT = 60;
// Font size in points
static final int FONT_SIZE = 11;
Now, when do any drawing, always use points converted to pixels:
static int toPixels(int value) {
return value * PIXELS_PER_POINT;
}
BufferedImage draw() {
BufferedImage image =
new BufferedImage(toPixels(IMAGE_WIDTH), toPixels(IMAGE_HEIGHT), TYPE_INT_ARGB);
Graphics2D g = image.createGraphics();
// <graphics init code goes here>
Font font = new Font("Arial", Font.PLAIN, toPixels(FONT_SIZE));
g.setFont(font);
g.drawString("Grapes", toPixels(5), toPixels(40)); // coordinates are in points
g.dispose()
return image;
}
So, with this approach you can operate with 'standard' dimentions. This approach works quite well for me for low- and medium complexity drawings.
You can go further and convert PIXELS_PER_POINT to a parameter: use 1x for images on web-pages with ordinary display, 2x for Retina displays and 4x for printing!

To fix the jagged edges in text or shapes in Graphics2d you need to set RenderingHint.
Graphics2D g2d = bufferedImage.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
Explanation
A typical antialiasing algorithm works by blending the existing colors of the pixels along the boundary of a shape with the requested fill paint according to the estimated partial pixel coverage of the shape.
Text antialiasing hint key. The TEXT_ANTIALIASING hint can control the use of antialiasing algorithms for text independently of the choice used for shape rendering. Often an application may want to use antialiasing for text only and not for other shapes. Additionally, the algorithms for reducing the aliasing artifacts for text are often more sophisticated than those that have been developed for general rendering so this hint key provides additional values which can control the choices of some of those text-specific algorithms. If left in the DEFAULT state, this hint will generally defer to the value of the regular KEY_ANTIALIASING hint key.

Related

Graphics2D - identical text rendering on all platforms

Is it possible to render pixel-by-pixel identical result with Graphics2D.drawString on all java platforms with same font? I tried to render text without antialiasing, but results differs on different machines. I use font from project resources, so font is system-independent.
Example of results of same code with same font on two different PCs:
I'm used very small font size (9 px) for clarity.
import java.awt.Color;
import java.awt.Font;
import java.awt.FontFormatException;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
public class Test {
public static void main(String... args) throws FontFormatException, IOException {
int x = 0;
int y = 9;
int width = 80;
int height = 10;
float fontSizeInPixels = 9f;
String text = "PseudoText";
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D graphics = image.createGraphics();
graphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
URL fontUrl = new URL(
"https://github.com/indvd00m/graphics2d-drawstring-test/blob/master/src/test/resources/fonts/DejaVuSansMono/DejaVuSansMono.ttf?raw=true");
Font font = Font.createFont(Font.TRUETYPE_FONT, fontUrl.openStream());
font = font.deriveFont(fontSizeInPixels);
Color fontColor = Color.BLACK;
Color backgroundColor = Color.WHITE;
graphics.setFont(font);
graphics.setColor(backgroundColor);
graphics.fillRect(0, 0, width, height);
graphics.setColor(fontColor);
graphics.drawString(text, x, y);
ImageIO.write(image, "png", new File("/tmp/test.png"));
}
}
I'm created project for test here:
https://github.com/indvd00m/graphics2d-drawstring-test
Failed build of this project:
https://travis-ci.org/indvd00m/graphics2d-drawstring-test/builds/178672466
Tests passed under openjdk6 and openjdk7 on linux but failed under oraclejdk7 and oraclejdk8 on linux and other OS and java versions.
Rendering text is extremely complex (evolving Opentype and Unicode specs, trying to fit small symbols on screens with too few pixels, work-arounding font bugs, etc).
It is so complex it is mostly system-dependent, with one remaining rendering engine per major OS. Those engines are continuously evolving to try to fix problems, support hardware changes and new spec revisions. They do not give the same results from system to system and OS version to OS versions. Sometimes apps like Oracle JDK add one more level of complexity by including their own rendering routines (for legacy compat, Open JDK uses the system rendering directly and gives better results on modern *nix systems).
You can try to erase some of the differences by rendering at very high pixel dimensions. That will remove all the lowdpi grid fitting black magic differences, and render close to the ideal high-quality paper printing. However the text will be very hard to read when scaled down to actual screen pixels.
In the meanwhile, differing interpretations on where and how put text pixels for better reading quality are a fact of life. You'd better not try to code anything that assumes otherwise. The text stack people will win, it's a very Darwinian process, the few text rendering engines that remain are survivors.
OK.. not sure this constitutes an 'answer' as such (more an experiment) but this is what I mean about scaling the text to fit the space. See comments in code.
import java.awt.*;
import java.awt.font.*;
import java.awt.geom.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URL;
import javax.imageio.ImageIO;
public class TestFontWidthScaling {
private static Font font;
private static float fontSizeInPixels = 36f;
private static String text = "PseudoText";
private static int width = 320;
private static int height = 40;
private static BufferedImage scaleImageToFit() {
BufferedImage image = new BufferedImage(
width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D graphics = image.createGraphics();
// graphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
// graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
// we need line antialiasing here
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
FontRenderContext frc = graphics.getFontRenderContext();
// this is important for determining the *current* size of the
// text using this font.
Area area = new Area(font.
createGlyphVector(frc, text).
getOutline());
Rectangle2D bounds = area.getBounds2D();
double w = bounds.getWidth();
double h = bounds.getHeight();
double scaleW = width*.95 / w;
double scaleH = height*.9 / h;
AffineTransform scale = AffineTransform.getScaleInstance(scaleW, scaleH);
// we now have the shape of the text that will fill a fixed percentage
// of the width and height of the assigned space.
area = area.createTransformedArea(scale);
// now to center it
bounds = area.getBounds2D();
double moveX = bounds.getCenterX() - width/2;
double moveY = bounds.getCenterY() - height/2;
AffineTransform move = AffineTransform.getTranslateInstance(-moveX, -moveY);
// this should be both scaled to size AND centered in the space
area = area.createTransformedArea(move);
Color fontColor = Color.BLACK;
// changed to make image bounds more obvious on white BG
Color backgroundColor = Color.CYAN;
graphics.setFont(font);
graphics.setColor(backgroundColor);
graphics.fillRect(0, 0, width, height);
graphics.setColor(fontColor);
graphics.draw(area);
graphics.fill(area);
return image;
}
public static void main(String... args) throws FontFormatException, IOException {
int x = 0;
int y = 36;
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D graphics = image.createGraphics();
graphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
URL fontUrl = new URL(
"https://github.com/indvd00m/graphics2d-drawstring-test/blob/master/src/test/resources/fonts/DejaVuSansMono/DejaVuSansMono.ttf?raw=true");
font = Font.createFont(Font.TRUETYPE_FONT, fontUrl.openStream());
font = font.deriveFont(fontSizeInPixels);
Color fontColor = Color.BLACK;
Color backgroundColor = Color.WHITE;
graphics.setFont(font);
graphics.setColor(backgroundColor);
graphics.fillRect(0, 0, width, height);
graphics.setColor(fontColor);
graphics.drawString(text, x, y);
String userHome = System.getProperty("user.home");
File f = new File(userHome);
f = new File(f, "test.png");
ImageIO.write(image, "png", f);
Desktop.getDesktop().open(f);
BufferedImage scaledImage = scaleImageToFit();
f = new File(f.getParentFile(), "test-scaled.png");
ImageIO.write(scaledImage, "png", f);
Desktop.getDesktop().open(f);
}
}

My compiler is giving me issues. How can I convert my Java Application into an Applet? [duplicate]

This question already has answers here:
javac is not recognized as an internal or external command, operable program or batch file [closed]
(6 answers)
Closed 7 years ago.
I've been tasked with creating a very simple webpage that includes a Java applet of a vehicle that moves across the screen and stops before leaving the window. I'm new to Java, so although I was able to successfully create an application that will do what I want, I'm not having any luck converting the application into an applet. Here is my code:
package finalProject;
import java.awt.Color;
import java.awt.Container;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.GeneralPath;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Car extends JFrame {
private static final long serialVersionUID = -5306640844197169382L;
public static void main(String[] args) {
JFrame GUI = new JFrame();
GUI.setTitle("Final Project");
double width = java.awt.Toolkit.getDefaultToolkit().getScreenSize().getWidth();
int w = (int) width;
GUI.setSize(w, 210);
GUI.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
drawCar van = new drawCar();
Container vanPane = GUI.getContentPane();
vanPane.add(van);
GUI.setVisible(true);
for(int i = 0; i <= w - 332; i++) {
van.setLayout(null);
van.setLocation(i += 1, 0);
try {
Thread.sleep(12);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class drawCar extends JPanel {
private static final long serialVersionUID = 4320980242217677298L;
int width = getWidth();
int height = getHeight();
public void paint (Graphics g) {
Color bodyRed = new Color (255, 0, 0);
Color tailLightRed = new Color (168, 0, 0);
Color handle = new Color (196, 196, 196);
Color tire = new Color (36, 36, 36);
Color hubCap = new Color (255, 128, 48);
Color headLamp = new Color (255, 255, 194);
Color smoke = new Color (41, 41, 41);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
Font font = new Font("Sans-serif", Font.ITALIC, 9);
g2.setFont(font);
// rear bumper
g.setColor(Color.white);
g.fillRect(15, 140, 25, 10);
g.setColor(Color.black);
g.drawRect(15, 140, 25, 10);
// running board
g.setColor(Color.white);
g.fillRect(90, 140, 140, 10);
g.setColor(Color.black);
g.drawRect(90, 140, 140, 10);
...
}
}
I run into trouble when I try to compile the file (Car.java). I've tried several different methods for compiling Car.java. This is the error message that I most often see:
'javac' is not recognized as an internal or external command, operable program or batch file.
I have added the location path of javac.exe to the list of Environment Variables, but as far as I can tell, it hasn't done any good. I'm still told that 'javac' isn't recognized. If I changed the directory to the location of javac.exe and try to compile, then javac.exe works, but I am told that Car.java is not found. If I then use -sourcepath to identify the location of Car.java, then this is what comes up:
javac: no source files
Is it possible to turn this application into an applet without running it through a compiler? In other words, can I just modify the code in the .java file and change it to a .class file?
I'm also open to hearing if my code could be improved; however, since my code (even if not ideal) still creates the desired effect, my main focus right now is getting this turned into an applet.
Could you show your modified PATH variable?
The easiest solution is running javac with the full path from your source code location:
c:\location_of_CarJava>"c:\Program Files\Java\jdk1.8.0_45\bin\javac.exe" ...

Why is my text-to-image method returning a fully-black image?

I'm trying to make a method that converts a given String (and Font) into a BufferedImage. However, every time I run it, it returns a fully black image. The exact size of the image seems to be correct, but all pixels are perfectly black.
Here's the code:
static final GraphicsEnvironment GE;
static
{
GE = GraphicsEnvironment.getLocalGraphicsEnvironment();
}
public static BufferedImage textToImage(String text, Font font)
{
if (font == null)
font = Font.getFont("Courier New");
FontRenderContext frc = new FontRenderContext(new AffineTransform(), false, false);
Rectangle2D bounds = font.getStringBounds(text, frc);
BufferedImage bi = new BufferedImage(
(int)(bounds.getWidth() + .5),
(int)(bounds.getHeight() + .5),
BufferedImage.TYPE_BYTE_BINARY
);
Graphics2D g = GE.createGraphics(bi);
g.setFont(font);
g.drawString(text, 0, 0);
return bi;
}
Here's "Hello World" in the default JOptionPane font displayed as a JOptionPane's icon:
The simple solution would be to change the color...
g.setColor(Color.WHITE);
g.fillRect(0, 0, bi.getWidth(), bi.getHeight());
g.setColor(Color.BLACK);
g.setFont(font);
g.drawString(text, 0, 0);
g.dispose();
Text, generally, isn't rendered from the y position down, it draw's up AND down from the y position, so you'll need to use something like...
FontMetrics fm = g.getFontMetrics();
g.drawString(text, 0, fm.getAscent());
to get the text to appear correctly...
Also font = Font.getFont("Courier New"); isn't doing what you think it is, this won't return the font named "Courier New", but will instead attempt to load the font file called "Courier New".
Try using something like...
if (font == null) {
font = new Font("Courier New", Font.PLAIN, 12);
}
instead...
You might like to take a closer look at Working with Text APIs for more details

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

Passing JRAbstractSvgRenderer (JRRenderable) in fillReport

I'm passing a simple implementation of JRAbstractSvgRenderer (taken from the ireports pdf manual) as one of the parameters using JasperFillManager.fillReport.
public class CustomImageRenderer extends JRAbstractSvgRenderer {
#Override
public void render(Graphics2D g2d, Rectangle2D rect) throws JRException {
System.out.println("CustomImageRenderer.render");
// Save the Graphics2D affine transform
AffineTransform savedTrans = g2d.getTransform();
Font savedFont = g2d.getFont();
// Paint a nice background...
g2d.setPaint(new GradientPaint(0, 0, Color.ORANGE,
0, (int) rect.getHeight(), Color.PINK));
g2d.fillRect(0, 0, (int) rect.getWidth(), (int) rect.getHeight());
Font myfont = new Font("Arial Black", Font.PLAIN, 50);
g2d.setFont(myfont);
FontRenderContext frc = g2d.getFontRenderContext();
String text = new String("JasperReports!!!");
TextLayout textLayout = new TextLayout(text, myfont, frc);
Shape outline = textLayout.getOutline(null);
Rectangle r = outline.getBounds();
// Translate the graphic to center the text
g2d.translate(
(rect.getWidth() / 2) - (r.width / 2),
rect.getHeight() / 2 + (r.height / 2));
g2d.setColor(Color.BLACK);
g2d.draw(outline);
// Restore the Graphics2D affine transform
g2d.setFont(savedFont);
g2d.setTransform(savedTrans);
}
}
...
Map parameters = new HashMap();
parameters.put("IMAGEPARAM", new CustomImageRenderer());
...
JasperPrint jasperPrint = JasperFillManager.fillReport(path, parameters, conn);
I have linked an Image component in my report to this parameter but the image does not display. What am I missing here?
What I'd like to accomplish is to eventually pass an already created Java2D image to my report but I don't want pass it as a raster image.
I don't know JasperReports, but you can create an off-screen java.awt.Image easily:
private Image getImage(int h, int w) {
BufferedImage bi = new BufferedImage(h, w, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = bi.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
// your drawing code
g2d.dispose();
return bi;
}
As a handy way to preview a rendering, you can create a JComponent that displays the image, e.g.:
JLabel label = new JLabel(new ImageIcon(getImage(h, w)));
Addendum: You might also try to determine if your renderer is being invoked at all or if it is somehow rendering nothing. If the latter, you might simplify your rendering code to some bare minimum such as setting the color and filling rect.

Categories

Resources