Java 2D uses Xrender or OpenGL on Linux, Metal or OpenGL on macOS and Direct3D on Windows.
This is a difficult question to answer without knowing what exact performance problems you face. You could start by using normal Java profiling tools to see how much CPU and memory and GC overhead you have and by using Java 2D tracing (see the question about tracing) to see what code paths are being taken by rendering.
-Dsun.java2d.trace=[log[,timestamp]],[count],[out:<filename>],[help],[verbose]
See the trace property in
System Properties for Java 2D Technology.
BufferedImage createResizedCopy(Image originalImage,
int scaledWidth, int scaledHeight,
boolean preserveAlpha) {
int imageType = preserveAlpha ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
BufferedImage scaledBI = new BufferedImage(scaledWidth, scaledHeight, imageType);
Graphics2D g = scaledBI.createGraphics();
if (preserveAlpha) {
g.setComposite(AlphaComposite.Src);
}
g.drawImage(originalImage, 0, 0, scaledWidth, scaledHeight, null);
g.dispose();
return scaledBI;
}import java.awt.*;
import java.awt.image.*;
import javax.imageio.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class ImageServlet extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("image/jpeg");
// Create image
int width=200, height=200;
BufferedImage image =
new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// Get drawing context
Graphics2D g2d = image.createGraphics();
// Fill background with white
g2d.setColor(Color.WHITE);
g2d.fillRect(0, 0, width, height);
// Draw a smiley face
g2d.setColor(Color.YELLOW);
g2d.fillOval(10, 10, 180, 180);
g2d.setColor(Color.BLACK);
g2d.fillOval(40, 40, 40, 40);
g2d.fillOval(120, 40, 40, 40);
g2d.fillRect(50, 150, 100, 10);
// Dispose context
g2d.dispose();
// Write image to the output stream
ServletOutputStream os = response.getOutputStream();
ImageIO.write(bi, "jpeg", os);
}
}java.awt.Graphics2D.drawString()
draws a String of text using the current font and other rendering
attributes. This is the most direct way to render text. See
Rendering Graphics Primitives.java.awt.font.TextLayout object
allows you to implement text editing yourself: it includes mixed
styles, BIDI text layout, carets, highlighting, hit testing and
many other features. See Managing Text Layout.java.awt.font.GlyphVector enables
you to have total control over how text is shaped and positioned. See
Implementing a Custom Text Layout Mechanism.JTextField, JTextArea,
and JEditorPane, which supports editing and multiple
fonts and styles, all utilize the previously mentioned Java 2D APIs.
Consequently, instead of not directly using the 2D text APIs,
you can use the UI-oriented Swing interfaces. See
Using Text Components in The Java Tutorials.OpenType and Type1
No
java.awt.GraphicsEnvironment.getAvailableFontFamilyNames()java.awt.GraphicsEnvironment.getAllFonts()java.awt.GraphicsEnvironment.getAvailableFontFamilyNames()You can load custom fonts dynamically by using the following methods:
java.awt.Font.createFont() to create a Font
object from a file or streamjava.awt.Font.deriveFont() to derive new Font
objects with varying sizes, styles, transforms, and font featuresjava.awt.Font.registerFont() to register the created
font with the graphics environment; once you have done so, the font is available
in calls to getAvailableFontFamilyNames() and can be used in font constructorsSee Bundling Physical Fonts with Your Application in The Java Tutorials.
Call the method java.awt.Toolkit.getScreenResolution() to obtain the screen resolution in dots-per-inch.
Font.canDisplay()
Use the system property awt.useSystemAAFontSettings:
java -Dawt.useSystemAAFontSettings=lcd
false corresponds to disabling font smoothing on the desktop. See java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT.on corresponds to Gnome Best shapes/Best contrast (there is no equivalent Windows desktop setting). See java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_ON.gasp corresponds to Windows "Standard" font smoothing. See java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_GASP.lcd corresponds to Gnome's "subpixel smoothing" and Windows "ClearType". See java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB.See
awt.useSystemAAFontSettings in System Properties for Java 2D Technology.
Call the method java.awt.Graphics.getFontMetrics(), which returns the
font metrics of the graphics content's current font or
java.awt.Graphics.getFontMetrics(Font),
which returns the font metrics of the specified font. Both of
these methods return an instance of FontMetrics.
Logical bounds are the most commonly used and include the
ascent, descent, leading and advance of the text. They are useful
to position the text correctly, particularly when appending one
string after another or for multiple lines of text but they very
likely will not enclose the rendered image. Particular examples
of this may be glyphs which extend a pixel to the left of the
"origin" at which it is drawn. "W" is a particular example – the
leftmost long diagonal may extend to the left of the rendering
origin. Glyphs in italic fonts may commonly extend further to
the right than the overall "advance" of the text may indicate.
These two issues may lead to text being clipped on the left or
the right if placed in a tight area measured using the advance of
the string. Adding a couple of pixels of padding at each end is
probably the simplest workaround for this. Similarly, large
descenders, or diacritics that are used in European languages, may
extend beyond the reported descent or ascent. If they are used to create a
tight bounding box for a label, for example, they may clip at the
bottom or top. Extra padding is again the simplest solution. To
get the logical bounds of a String, use any of following
methods as appropriate:
Font.getStringBounds(...)TextLayout.getAscent()TextLayout.getDescent()TextLayout.getLeading()TextLayout.getAdvance()GlyphVector.getLogicalBounds(...)GlyphVector.getVisualBounds(...)GlyphVector.getPixelBounds(...)TextLayout.getPixelBounds(...)TextLayout.getPixelBounds(...)java.awt.PrintJob
java.awt.print.PrinterJob
javax.print packages
See the print methods in the javax.swing.JTable class
and Printing Support in Swing Components
in The Java Tutorials.
BufferedImage
and then draw that BufferedImage to
the printer graphics.javax.print.attribute.standard.PrinterResolution class.public int print(Graphics g, PageFormat pf, int pageIndex)
throws PrinterException {
Graphics2D g2 = (Graphics2D)g;
g2.translate(pf.getImageableX(),
pf.getImageableY() + 72);
// ...
}public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException {
if (pageIndex > 0) return Printable.NO_SUCH_PAGE;
Graphics2D g2d = (Graphics2D) graphics;
// Set us to the upper left corner
g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY());
AffineTransform at = new AffineTransform();
at.translate(0,0);
// We need to scale the image properly so that it fits on one page.
double xScale = pageFormat.getImageableWidth() / m_image.getWidth();
double yScale = pageFormat.getImageableHeight() / m_image.getHeight();
// Maintain the aspect ratio by taking the min of those 2 factors and
// using it to scale both dimensions.
double aspectScale = Math.min(xScale, yScale);
g2d.drawRenderedImage(m_image, at);
return Printable.PAGE_EXISTS;
}See Specifying Document Types for information about how to accurately describe print data to the print service with a DocFlavor.
This might happen if CUPS is listening to a local domain socket as well as localhost.
/etc/cups/cupsd.conf
and uncomment the following line:
# Listen /var/run/cups/cups.sock
Port 631
sh /etc/init.d/cups restart cd /usr/lib ln -s libcups.so.2 libcups.so
See JDK-6500903 : PrintServices are incorrectly listed as "not accepting jobs" for more information.
See Java 2D Rendering in The Java Tutorials.
The following are terms related to Java 2D rendering:
draw methods.| Arc2D | Represents an arc defined by a bounding rectangle, start angle, angular extent, and a closure type. |
| CubicCurve2D | Represents a cubic parametric curve segment. |
| Ellipse2D | Represents an ellipse defined by a bounding rectangle. |
| Line2D | Represents a line segment in (x, y) coordinate space. |
| Point2D | A point representing a location in (x,y) coordinate space. Points render nothing when drawn or filled, but the Point2D class is used in many of the APIs that manipulate or construct shapes. |
| QuadCurve2D | Represents a quadratic parametric curve segment. |
| Rectangle2D | Represents a rectangle defined by a location (x, y) and dimension (w x h). |
| RoundRectangle2D | Represents a rectangle with rounded corners defined by a location (x, y), a dimension (w x h), and the width and height of the corner arcs. |
In addition to these classes that enable you to create common
shapes, the Java 2D API provides two other classes that allow you
to define odd shapes: GeneralPath and Area. Shapes created with
GeneralPath must be created segment by segment, but this means
that you can combine straight lines and curved lines into a
single shape. The Area class supports constructive area geometry,
which enables you to combine two shapes to create another shape,
either by adding or intersecting the shapes, subtracting one
shape from another, or by subtracting the intersection of the
shapes.
You can also create a Shape object from a String by calling
getOutline on a TextLayout object. After creating the Shape, you
can perform operations such as filling and transforming on the
Shape.
For more information on working with shapes in Java 2D, see the 2D Graphics tutorial.
BufferedImage bi = null;
try {
bi = ImageIO.read(new File("images/bld.jpg"));
} catch (IOException ioe) {
// ...
}
Graphics2D g2d = bi.createGraphics();
g2d.drawLine(10, 10, 20, 20); // draw a line on the image
// ...
g2d.dispose();Use one of the winding rules,
Path2D.WIND_EVEN_ODD or
Path2D.WIND_NON_ZERO, when creating a geometric path with Path2D.
GeneralPath path = new GeneralPath(); float p1x = 10, p1y = 10; // P1 float p2x = 100, p2y = 10; // P2 float cx = 55, cy = 50; // Control point of the curve float arrSize = 5; // Size of the arrow segments float adjSize = (float)(arrSize/Math.sqrt(2)); float ex = p2x - cx; float ey = p2y - cy; float abs_e = (float)Math.sqrt(ex*ex + ey*ey); ex /= abs_e; ey /= abs_e; // Creating quad arrow path.moveTo(p1x, p1y); path.quadTo(cx, cy, p2x, p2y); path.lineTo(p2x + (ey-ex)*adjSize, p2y - (ex + ey)*adjSize); path.moveTo(p2x, p2y); path.lineTo(p2x - (ey + ex)*adjSize, p2y + (ex - ey)*adjSize);
To perform transformations, use these steps:
Use getTransform to get the current transform:
AffineTransform aT = g2.getTransform();
Use the transform, translate, scale, shear, or rotate methods to concatenate a transform:
g2.transform(...);
Perform the rendering:
g2.draw(...);
Restore the original transform using setTransform:
g2.setTransform(aT);