当前位置: 首页 > 知识库问答 >
问题:

使用PrinterJob打印图像(Graphics2D)

宫弘亮
2023-03-14

有没有一种方法我可以在Java中操纵一个PrinterJob而不是实际打印到打印机上,这样我就可以获得每一页的图形对象?我尝试将PrintService设置为null,但Java不允许这样做。

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

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

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;
}

你已经可以看到图形对象被记录了,这样我就可以在另一个组件中绘制它们了,但是这是相当无用的,因为它会在记录完成之前将它们发送到我的打印机。

共有1个答案

顾磊
2023-03-14

基本上,您希望创建您自己的graphics上下文,以供您绘制。您还需要构造一个PageFormat,它可以传递给Print方法。

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;
    }
}

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

 类似资料:
  • 编辑:所以在一天的混乱之后。我的问题是spintf。我最初认为我的循环是错误的。

  • 问题内容: 我目前在使用默认打印机打印jpeg文件时陷入困境。在我的程序中,当我从文件夹中选择图像时,我需要使用打印机默认设置(纸张尺寸,边距,方向)进行打印。 目前我得到这个: 现在,我的打印机的默认大小设置为:10 x 15厘米(4 x 6英寸),但是当我将程序设置为打印给定图像时,它仅显示一小部分纸张。 请帮帮我。 问题答案: 首先,请确保您将上下文翻译成适合可成像的区域… 接下来,请确保您

  • 问题内容: 我需要用Java打印图像。因此我实现了接口方法。但是打印机始终只打印一些原始图像。如何使图像适合打印区域(A4),以便打印机能够打印整个图像,而不是整个图像?现在我的代码如下: 问题答案: 您需要按比例缩小图像以适合可用区域。

  • 使用飞碟以PDF格式打印图像。 超文本标记语言代码: 当我使用飞碟将HTML转换为PDF时。生成的PDF不会打印图像。 我需要使用任何特定的软件包来打印PDF格式的图像吗。如果你有任何问题,请告诉我。

  • 问题内容: 是否可以在Internet选项的“高级”选项卡中不启用“打印背景色和图像”的情况下打印背景图像? 我认为可以使用没有“背景图像”的替代方法…使用div标签和绝对位置可以模拟背景图像的相同效果吗?我也想在页面上重复背景图像。 问题答案: 打印背景图像(在标记中指定为背景图像的那些图像)的能力完全取决于最终用户,您无法从代码中以编程方式控制此功能。Firefox的一个插件提供了JavaSc

  • 问题内容: 我想打印这样的东西 图片 标题 捷普 我知道要在messageFormat标头中打印带有标题的jtable,但我不知道如何添加图像 图像是徽标 问题答案: 您可以尝试此处显示的方法。使用而不是在您的可打印物中。