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

查看:547
本文介绍了使用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;
}

您可以看到图形对象被记录,以便我可以绘制在另一个组件中,但是在完成记录之前,会看到它将继续发送到我的打印机是非常无用的。

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 上下文。您还需要构建一个可以超过打印方法的 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天全站免登陆