Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
获取Java打印机图形设备_Java_Graphics_Printing - Fatal编程技术网

获取Java打印机图形设备

获取Java打印机图形设备,java,graphics,printing,Java,Graphics,Printing,JavaDocs表明GraphicsEnvironment支持“屏幕和打印机设备” 我能看到如何获取有关屏幕设备的信息,但似乎无法找到有关如何获取打印机设备信息的信息 基本上,在打印时,我希望能够使用devices GraphicsConfiguration创建兼容的缓冲图像 希望这样做的主要原因是: 我们希望在页面的第一个请求上缓冲页面请求,并在页面的后续请求上简单地绘制回缓冲区(因为页面包含大量图像和一些复杂的呈现-而不是浪费时间绘制每个页面请求,我们希望使用缓冲区) 保持打印机的高分辨率输

JavaDocs表明GraphicsEnvironment支持“屏幕和打印机设备”

我能看到如何获取有关屏幕设备的信息,但似乎无法找到有关如何获取打印机设备信息的信息

基本上,在打印时,我希望能够使用devices GraphicsConfiguration创建兼容的缓冲图像

希望这样做的主要原因是:

  • 我们希望在页面的第一个请求上缓冲页面请求,并在页面的后续请求上简单地绘制回缓冲区(因为页面包含大量图像和一些复杂的呈现-而不是浪费时间绘制每个页面请求,我们希望使用缓冲区)
  • 保持打印机的高分辨率输出。我们发现,如果我们直接在打印机的图形上下文中绘制,我们会获得实质上更高的质量输出,而如果我们尝试使用相同大小的缓冲图像,则会获得更高的质量输出
  • 我尝试过搜索JavaDocs和Google,但运气不好

    有什么建议吗

    干杯

    根据其他想法进行更新

    基于其他想法,有人建议尝试使用类似于

    GraphicsConfiguration conf = ((Graphics2D) graphics).getDeviceConfiguration();
    assert conf.getDevice().getType() == GraphicsDevice.TYPE_PRINTER;
    System.out.println("Device: " + conf.getDevice().getIDstring());
    
    final AffineTransform trans = conf.getDefaultTransform();
    double dpi = trans.transform(new Point2D.Float(72, 0), null).getX();
    System.out.println(dpi + " DPI");
    
    Rectangle bounds = conf.getBounds();
    System.out.println("page size: " + bounds.width + "x" + bounds.height);
    // now you could do
    buffer = conf.createCompatibleImage(bounds.width, bounds.height);
    // verify values, you wouldn’t do this in production code:
    
    g2d.drawImage(buffer, 0, 0, (int) pageFormat.getImageableWidth(), (int) pageFormat.getImageableWidth(), null);
    
    double scale = dpi / 72d;
    AffineTransform scaleAT = AffineTransform.getScaleInstance(scale, scale);
    g2d.setTransform(scaleAT);
    print(g2d, pageFormat.getImageableWidth(), pageFormat.getImageableWidth());
    
    它实际上会生成一个
    缓冲图像
    ,该图像将被转换为打印机DPI

    为了简化测试,我编写了一个简单的
    print
    方法

    public void print(Graphics2D g2d, double width, double height) {
        Font font = g2d.getFont();
        font = font.deriveFont(64f);
        g2d.setFont(font);
        FontMetrics fm = g2d.getFontMetrics();
        String text = "Hello World!";
        double x = (width - fm.stringWidth(text)) / 2;
        double y = (height - fm.getHeight()) / 2;
        g2d.drawString(text, (float) x, (float) y);
    }
    
    我可以使用打印机
    图形
    上下文或其他
    图形
    上下文

    现在很明显,当以72dpi打印到A4页面时,生成的图像大小为595x841,为600dpi(上面的示例已报告),这将生成4970x7029的图像。好的,这很好,我只需要在绘制到目标打印机
    Graphics
    context时缩小图像的比例,例如

    GraphicsConfiguration conf = ((Graphics2D) graphics).getDeviceConfiguration();
    assert conf.getDevice().getType() == GraphicsDevice.TYPE_PRINTER;
    System.out.println("Device: " + conf.getDevice().getIDstring());
    
    final AffineTransform trans = conf.getDefaultTransform();
    double dpi = trans.transform(new Point2D.Float(72, 0), null).getX();
    System.out.println(dpi + " DPI");
    
    Rectangle bounds = conf.getBounds();
    System.out.println("page size: " + bounds.width + "x" + bounds.height);
    // now you could do
    buffer = conf.createCompatibleImage(bounds.width, bounds.height);
    // verify values, you wouldn’t do this in production code:
    
    g2d.drawImage(buffer, 0, 0, (int) pageFormat.getImageableWidth(), (int) pageFormat.getImageableWidth(), null);
    
    double scale = dpi / 72d;
    AffineTransform scaleAT = AffineTransform.getScaleInstance(scale, scale);
    g2d.setTransform(scaleAT);
    print(g2d, pageFormat.getImageableWidth(), pageFormat.getImageableWidth());
    
    (这是测试,所以现在还不要就质量相关的问题向我发火)

    (左侧为正常,
    buffereImage
    右侧为正常)…好的,这样不行

    因此,我当时想,我可以对缓冲区
    Graphics
    上下文应用
    AffineTransform
    缩放,使用类似于

    GraphicsConfiguration conf = ((Graphics2D) graphics).getDeviceConfiguration();
    assert conf.getDevice().getType() == GraphicsDevice.TYPE_PRINTER;
    System.out.println("Device: " + conf.getDevice().getIDstring());
    
    final AffineTransform trans = conf.getDefaultTransform();
    double dpi = trans.transform(new Point2D.Float(72, 0), null).getX();
    System.out.println(dpi + " DPI");
    
    Rectangle bounds = conf.getBounds();
    System.out.println("page size: " + bounds.width + "x" + bounds.height);
    // now you could do
    buffer = conf.createCompatibleImage(bounds.width, bounds.height);
    // verify values, you wouldn’t do this in production code:
    
    g2d.drawImage(buffer, 0, 0, (int) pageFormat.getImageableWidth(), (int) pageFormat.getImageableWidth(), null);
    
    double scale = dpi / 72d;
    AffineTransform scaleAT = AffineTransform.getScaleInstance(scale, scale);
    g2d.setTransform(scaleAT);
    print(g2d, pageFormat.getImageableWidth(), pageFormat.getImageableWidth());
    
    这意味着我不需要在我们现有的底层绘制例程中应用任何“打印模式”类型转换

    这导致

    但是等一下,这里出了什么问题

    所以我回去看了所有的测量结果

    GraphicsConfiguration conf = ((Graphics2D) graphics).getDeviceConfiguration();
    //...
    Rectangle bounds = conf.getBounds();
    buffer = conf.createCompatibleImage(bounds.width, bounds.height);
    
    我们报告的图像大小是4960x7015,但它应该是4970x7029…但是等等,想象中的区域呢…应该是600dpi,3768x5827…所以这是不可靠的

    即使纠正了这一点,结果仍然没有让图像在位置和质量上与预期相符


    Graphics2D
    提供了一种获取链接到
    图形设备的
    图形配置的方法。缺少的是信息,您可以放心地假设在打印上下文中,
    图形
    图形2d

    例如,以下程序在我的设置中起作用:

    import java.awt.*;
    import java.awt.geom.*;
    import java.awt.image.BufferedImage;
    import java.awt.print.*;
    import javax.print.*;
    
    public class PrintDev implements Printable {
      public static void main(String[] args) throws PrintException {
        final DocFlavor flavor = DocFlavor.SERVICE_FORMATTED.PRINTABLE;
        PrintService ps=PrintServiceLookup.lookupDefaultPrintService();
        System.out.println(ps.getName());
        ps.createPrintJob().print(new SimpleDoc(new PrintDev(), flavor, null), null);
      }
      @Override
      public int print(Graphics graphics, PageFormat pageFormat, int pageIndex)
          throws PrinterException {
        GraphicsConfiguration conf = ((Graphics2D)graphics).getDeviceConfiguration();
        assert conf.getDevice().getType()==GraphicsDevice.TYPE_PRINTER;
        System.out.println("Device: "+conf.getDevice().getIDstring());
        final AffineTransform trans = conf.getDefaultTransform();
        System.out.println(trans.transform(new Point2D.Float(72,0),null).getX()+" DPI");
        Rectangle bounds = conf.getBounds();
        System.out.println("page size: "+bounds.width+"x"+bounds.height);
        // now you could do
        BufferedImage bi=conf.createCompatibleImage(bounds.width, bounds.height);
        // verify values, you wouldn’t do this in production code:
        try { trans.invert(); }
        catch(NoninvertibleTransformException ex){ return NO_SUCH_PAGE; }
        Point2D p=trans.transform(new Point2D.Float(bounds.width, bounds.height),null);
        System.out.printf("page in inches: %.2fx%.2f%n", p.getX()/72, p.getY()/72);
        return NO_SUCH_PAGE;
      }
    }
    

    这个问题是关于Java Graphics2D或输出到HW打印机的大小的???@mKorbel两者都不是。就像您可以创建一个兼容的图像来渲染到屏幕上一样,我想用打印机也这样做。一般来说,如果创建缓冲图像并将其绘制到打印机的图形上下文中,它的渲染速度(我认为)为72dpi。如果你直接画图形,你就得到了印刷者的dpi。现在我的问题很清楚了:-)这可能会有帮助:真的吗?为什么这个问题会引起反对票?是否有人想进一步说明原因,以便我有机会纠正这个问题…?我按喇叭,我尝试了这个,但没有成功。我会重新测试以确定事实上,几个月前我尝试过类似的方法,但没有成功。仍然在测试所以为了完整性,它在
    Windows7 32位
    jdk 1.7.0(40
    …Windows7 x64,Java6,7和8上工作-仍然在测试;)这是否意味着它正在这些系统上工作?