【问题标题】:Java PrinterJob, high quality printing ends up with 72 DPI anywayJava PrinterJob,高质量打印最终以 72 DPI 结束
【发布时间】:2020-04-24 14:56:08
【问题描述】:

我正在尝试以 300 dpi 打印质量在 1 英寸 x 2 英寸标签上打印图像

public void print() {
        RepaintManager currentManager =  RepaintManager.currentManager(this);
        currentManager.setDoubleBufferingEnabled(false);

        PrinterJob job = PrinterJob.getPrinterJob();

        try {
            HashPrintRequestAttributeSet set = new HashPrintRequestAttributeSet();
            set.add(PrintQuality.HIGH);
            set.add(MediaSize.findMedia(2.125f, 1f, MediaSize.INCH));
            // 2" x 1" PrintableArea
            set.add(new MediaPrintableArea(1f/16f, 0f, 2.0f, 1f, MediaPrintableArea.INCH));
            set.add(new PrinterResolution(300, 300, ResolutionSyntax.DPI));
            set.add(OrientationRequested.PORTRAIT);
            job.setPrintable(this);
            job.setJobName("Label");
            job.print(set);
        } catch (PrinterException e) {
            // The job did not complete successfully
            e.printStackTrace();
        }
        currentManager.setDoubleBufferingEnabled(true);
    }

我的 BufferedImage 是 300 x 600 像素,应该适合

BufferedImage bi = freeze(this); //getting BufferedImage from JPanel
System.out.println("Image dim: "+bi.getWidth()+" X "+bi.getHeight());

控制台输出:图像暗淡:600 X 300。

但有问题的部分是当我打印出像这样的可成像尺寸时

        double x=pf.getImageableX();
        double y=pf.getImageableY();
        int w = (int)Math.round(pf.getImageableWidth());
        int h = (int)Math.round(pf.getImageableHeight());
        System.out.println("X: "+x);
        System.out.println("Y: "+y);
        System.out.println("W: "+w);
        System.out.println("H: "+h);

输出是:

X: 4.50141716003418
Y: 0.0
W: 144
H: 72

来自 h & w:我这里每英寸只有 72 个像素,任何调整大小都没有效果,这没有任何意义,

HashPrintRequestAttributeSet 请求 300 DPI 有什么用?

【问题讨论】:

    标签: java printing


    【解决方案1】:

    API docs of PageFormat#getImageableHeight() 明确表示:

    返回页面可成像区域的高度(以 1/72 英寸为单位)。此方法会考虑页面的方向。

    getImageableWidth() 的 API 文档类似。)

    当您将可打印区域指定为 2x1 英寸时(请参阅代码中的 MediaPrintableArea 属性),可成像的宽度和高度分别为 144。 72(1/72 英寸)。

    方法文档中没有关于 DPI 的一个词。

    【讨论】:

    • 感谢您的回复,但我的问题是“如何将 300 像素放入 72 像素?”任何缩放图形 g2d.scale() 或 getScaledInstance 的尝试都给出了 72 DPI 打印分辨率的相同结果,无论如何我刚刚完成了工作,但仍然不明白诀窍在哪里
    • @WalidKilany “72 DPI 打印分辨率”是什么意思?你怎么知道?正如我在回答中已经说过的那样,getImageableWidth() 确实 not 返回与实际打印分辨率相关的任何内容。除此之外,您将可打印区域设置为小至 1x2 英寸...
    【解决方案2】:

    奇迹刚刚发生,感谢“Marty Hall”提供本教程"Printing Swing Components in Java 1.2" 我所做的是:

    1- 不要在要打印的同一面板上实现可打印界面 2-使用实用程序类(在教程中提到来完成这项工作) 3-使用一个图形对象绘制所有组件(位置图像),不要堆叠/布局许多组件来绘制面板

    @Override
        public void paintComponent(Graphics g){
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g;
            RenderingHints rh = new RenderingHints(
                    RenderingHints.KEY_ANTIALIASING,
                    RenderingHints.VALUE_ANTIALIAS_ON);
            rh.put(RenderingHints.KEY_RENDERING,
                    RenderingHints.VALUE_RENDER_QUALITY);    
            g2d.setRenderingHints(rh);
    
            // Grids for testing porpose
            for(int i=50; i<=300; i+=50) {
                g2d.drawLine(i, 0, i, 600);
                g2d.drawString(""+i, i-20,20);
            }
            for(int i=100; i<=400; i+=100) {
                g2d.drawLine(0, i, 300, i);
                g2d.drawString(""+i, 10,i-10);
            }
            g2d.translate(0, 400);
            BufferedImage barcodeImage=getBarCode128(String.valueOf(1234567));
            g2d.drawImage(barcodeImage, 0, 0, 300, 200, null);
        }
    

    4- 将 HashPrintRequestAttributeSet 添加到 print() 方法中,因为“Marty Hall”类使用 printDialog() 来执行此操作,这不适用于我

    public void print() {
        PrinterJob printJob = PrinterJob.getPrinterJob();
    
        HashPrintRequestAttributeSet set = new HashPrintRequestAttributeSet();
        set.add(PrintQuality.HIGH);
        set.add(MediaSize.findMedia(1f, 2.125f, MediaSize.INCH));
        set.add(new MediaPrintableArea(0f, 1f/16f, 1f, 2.0f, MediaPrintableArea.INCH));
        set.add(new PrinterResolution(300, 300, ResolutionSyntax.DPI));
        set.add(OrientationRequested.PORTRAIT);
    
        printJob.setPrintable(this);
          try {
            printJob.print(set);
          } catch(PrinterException pe) {
            System.out.println("Error printing: " + pe);
          }
      }
    

    5-根据需要进行平移和缩放,然后打印面板

    public int print(Graphics g, PageFormat pf, int pageIndex) {
        if (pageIndex > 0) {
          return(NO_SUCH_PAGE);
        } else {
          Graphics2D g2d = (Graphics2D)g;
          g2d.translate(pf.getImageableX(), pf.getImageableY());
          g2d.scale(pf.getImageableWidth()/componentToBePrinted.getWidth(), pf.getImageableHeight()/componentToBePrinted.getHeight());
          disableDoubleBuffering(componentToBePrinted);
          componentToBePrinted.paint(g2d);
          enableDoubleBuffering(componentToBePrinted);
          return(PAGE_EXISTS);
        }
      }
    

    the final result is high resolution image readable barcode

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-02
      • 1970-01-01
      • 1970-01-01
      • 2013-04-18
      • 1970-01-01
      • 2023-04-03
      相关资源
      最近更新 更多