使用 PrinterJob 打印图像 (Graphics2D) [英] Using PrinterJob to print an Image (Graphics2D)

查看:42
本文介绍了使用 PrinterJob 打印图像 (Graphics2D)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有办法可以在 Java 中装配 PrinterJob 以不实际打印到打印机,以便我可以获得每个页面的图形对象?我尝试将 PrintService 设置为 null,但 Java 不允许这样做.

Is there a way I can rig a PrinterJob in Java to NOT actually print to a printer so that I can get the graphics objects for each page? I tried setting the PrintService to null, but Java wouldn't allow that.

这样我就可以检索文档的准确打印预览,而无需在不同的上下文中从头开始重新构建 PrinterJobs 函数.

This is so that I can retrieve an accurate Print Preview for the document without essentially rebuilding PrinterJobs functions from the ground-up in a different context.

这是我程序中打印函数的代码:

Here's the code for the print function in my program:

public int print(Graphics graphics, PageFormat pageFormat, int page) throws PrinterException {

    deepCopyString = string;

    FontMetrics metrics = graphics.getFontMetrics(font);
    int lineHeight = metrics.getHeight();

    arrangePage(graphics, pageFormat, metrics);

    if (page > pageBreaks.length){
        return NO_SUCH_PAGE;
    }

    Graphics2D g = (Graphics2D) graphics;

    g.translate(pageFormat.getImageableX(), pageFormat.getImageableY());
    g.setFont(font);

    int begin = (page == 0) ? 0 : pageBreaks[page-1];
    int end = (page == pageBreaks.length) ? lines.length : pageBreaks[page];

    int y = 0;
    int x = 0;

    for (int line = begin; line < end; line++){
        x = 0;
        y += lineHeight;

        checkSyntax(line);

        String l = lines[line];

        for (int c = 0; c < l.length(); c++){
            applySyntax(c, line);

            metrics = graphics.getFontMetrics(font);
            String ch = Character.toString(l.charAt(c));

            g.setFont(font);
            g.drawString(ch, x, y);

            x += metrics.charWidth(l.charAt(c));
            //System.out.println(c + "/"+l.length());
        }

        //g.drawString(lines[line], 0, y);
    }

    reset();

    records.add(g);

    return PAGE_EXISTS;
}

您已经可以看到 Graphics 对象已被记录,以便我可以在另一个组件中绘制它们,但是看到它是无用的,因为它会在记录完成之前将这些对象发送到我的打印机.

You can already see that the Graphics objects are recorded so that I can paint them in another component, but it's rather useless seeing as it will go ahead and send these to my printer before the record can be completed.

总的来说,这可能是个坏主意,而且我对打印还很陌生.如果这真的是一个糟糕的方法,请随时将我指向一个可以解释更好方法的来源.

This may be a bad idea in general, and I'm pretty new to printing. If this is seriously a bad way to go about this, feel free to direct me to a source that'll explain a better way.

推荐答案

基本上,您希望创建自己的 Graphics 上下文,您可以在其中进行绘制.您还需要构造一个可以传递给 print 方法的 PageFormat.

Basically, you want to create you own Graphics context to which you can paint. You also need to construct a PageFormat that can be past to the print method.

public class TestPrint implements Printable  {

    private BufferedImage background;
    public static final float DPI = 72;

    public static void main(String[] args) {
        new TestPrint();
    }

    public TestPrint() {

        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (Exception ex) {
                }

                try {
                    background = ImageIO.read(new File("C:/Users/shane/Dropbox/MegaTokyo/MgkGrl_Yuki_by_fredrin.jpg"));
                } catch (IOException ex) {
                    ex.printStackTrace();
                }

                float width = cmToPixel(21f, DPI);
                float height = cmToPixel(29.7f, DPI);

                Paper paper = new Paper();
                float margin = cmToPixel(1, DPI);
                paper.setImageableArea(margin, margin, width - (margin * 2), height - (margin * 2));
                PageFormat pf = new PageFormat();
                pf.setPaper(paper);

                BufferedImage img = new BufferedImage(Math.round(width), Math.round(height), BufferedImage.TYPE_INT_RGB);
                Graphics2D g2d = img.createGraphics();
                g2d.setColor(Color.WHITE);
                g2d.fill(new Rectangle2D.Float(0, 0, width, height));
                try {
                    g2d.setClip(new Rectangle2D.Double(pf.getImageableX(), pf.getImageableY(), pf.getImageableWidth(), pf.getImageableHeight()));
                    print(g2d, pf, 0);
                } catch (PrinterException ex) {
                    ex.printStackTrace();
                }
                g2d.dispose();

                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new JLabel(new ImageIcon(img)));
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);

            }
        });

    }

    public float cmToPixel(float cm, float dpi) {

        return (dpi / 2.54f) * cm;

    }

    public int print(Graphics graphics, PageFormat pageFormat, int page) throws PrinterException {

        if (page > 0) {
            return NO_SUCH_PAGE;
        }

        Graphics2D g = (Graphics2D) graphics;

        g.translate(pageFormat.getImageableX(), pageFormat.getImageableY());
        if (background != null) {

            int x = (int)Math.round((pageFormat.getImageableWidth() - background.getWidth()) / 2f);
            int y = (int)Math.round((pageFormat.getImageableHeight() - background.getHeight()) / 2f);

            g.drawImage(background, x, y, null);

        }

        g.setColor(Color.BLACK);
        g.draw(new Rectangle2D.Double(0, 0, pageFormat.getImageableWidth() - 1, pageFormat.getImageableHeight() - 1));

        return PAGE_EXISTS;
    }
}

现在,很明显,打印到屏幕上的内容和打印到打印机上的内容会有所不同,因为我们实际上使用的硬件设备不同,但基本概念适用

Now, obviously, there are going to be difference to what is printed to the screen and what's printed to the printer, because we're not actually using the same hardware device, but the basic concept applies

这篇关于使用 PrinterJob 打印图像 (Graphics2D)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆