当前位置: 首页 > 面试题库 >

如何在Java中设计要在300 dpi打印机上打印的图像

鲁羽
2023-03-14
问题内容

我想用Java制作图像,然后在尺寸为150 x
100毫米的标签上的300dpi标签打印机上打印。如何制作图像,以便将线条(或任何种类的元素)准确地打印在位置(10,10)(以毫米为单位),并在位置(10,50)处结束?

换句话说:我的挑战不是如何制作一条线(我使用的是Graphics2D,bufferedImage),而是如何准确地知道该行在标签上的位置(以毫米为单位)。

有任何想法吗?


问题答案:

Java的打印API基本上是在假设所有操作均以72 dpi的速度进行工作的。这意味着您可以以此为基础来进行不同测量之间的转换…

这只是意味着您需要开始值和目标测量…

// The number of CMs per Inch
public static final double CM_PER_INCH = 0.393700787d;
// The number of Inches per CMs
public static final double INCH_PER_CM = 2.545d;
// The number of Inches per mm's
public static final double INCH_PER_MM = 25.45d;

/**
 * Converts the given pixels to cm's based on the supplied DPI
 * @param pixels
 * @param dpi
 * @return 
 */
public static double pixelsToCms(double pixels, double dpi) {
    return inchesToCms(pixels / dpi);
}

/**
 * Converts the given cm's to pixels based on the supplied DPI
 * @param cms
 * @param dpi
 * @return 
 */
public static double cmsToPixel(double cms, double dpi) {
    return cmToInches(cms) * dpi;
}

/**
 * Converts the given cm's to inches
 * @param cms
 * @return 
 */
public static double cmToInches(double cms) {
    return cms * CM_PER_INCH;
}

/**
 * Converts the given inches to cm's 
 * @param inch
 * @return 
 */
public static double inchesToCms(double inch) {
    return inch * INCH_PER_CM;
}

因此,为了以10mmx10mm的分辨率打印图像,您需要将其转换为每英寸的像素

double point = cmsToPixel(1, 72);

您可能还需要考虑缩小图像尺寸以适合可打印区域。

举个例子…

  • 使图像适合打印区域
  • 使PrinterJob对象适合BufferedImage的特定打印格式

更新测试结果

所以我做了一些测试(代码如下)…

首先,我设置一个PrintRequestAttributeSet仅请求能够支持300x300 dpi的打印服务…

PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
aset.add(new PrinterResolution(300, 300, PrinterResolution.DPI));
aset.add(new MediaPrintableArea(0, 0, 150, 100, MediaPrintableArea.MM));

打印时,我Printable通过了425.20 x 283.46像素的可成像区域,相当于15.dpi x 10.02厘米@
72dpi(大约)。这就是Java的工作方式,它的基本打印API始终在72dpi的假设下工作。

所以。如果准备10 x 50毫米@ 72 DPI的图像,则图像尺寸为28.346 x 141.732像素,可以轻松放入可成像区域(425.20 x
283.46)。

但是,如果使用300 dpi,则会得到118.11 x 590.551像素的图像,这将使我们陷入麻烦,需要缩小图像的尺寸…

实际上,这可能是理想的,您必须执行一些测试才能找出答案。

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.MediaPrintableArea;
import javax.print.attribute.standard.PrinterResolution;

public class TestHiResPrinting {

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
                aset.add(new PrinterResolution(300, 300, PrinterResolution.DPI));
                aset.add(new MediaPrintableArea(0, 0, 150, 100, MediaPrintableArea.MM));

                PrinterJob pj = PrinterJob.getPrinterJob();
                pj.setPrintable(new PrintTask());

                if (pj.printDialog(aset)) {
                    try {
                        pj.print(aset);
                    } catch (PrinterException ex) {
                        ex.printStackTrace();
                    }
                }
            }
        });
    }

    // The number of CMs per Inch
    public static final double CM_PER_INCH = 0.393700787d;
    // The number of Inches per CMs
    public static final double INCH_PER_CM = 2.545d;
    // The number of Inches per mm's
    public static final double INCH_PER_MM = 25.45d;

    /**
     * Converts the given pixels to cm's based on the supplied DPI
     *
     * @param pixels
     * @param dpi
     * @return
     */
    public static double pixelsToCms(double pixels, double dpi) {
        return inchesToCms(pixels / dpi);
    }

    /**
     * Converts the given cm's to pixels based on the supplied DPI
     *
     * @param cms
     * @param dpi
     * @return
     */
    public static double cmsToPixel(double cms, double dpi) {
        return cmToInches(cms) * dpi;
    }

    /**
     * Converts the given cm's to inches
     *
     * @param cms
     * @return
     */
    public static double cmToInches(double cms) {
        return cms * CM_PER_INCH;
    }

    /**
     * Converts the given inches to cm's
     *
     * @param inch
     * @return
     */
    public static double inchesToCms(double inch) {
        return inch * INCH_PER_CM;
    }

    public static class PrintTask implements Printable {

        private BufferedImage img;

        public PrintTask() {
            double width = cmsToPixel(1, 72);
            double height = cmsToPixel(5, 72);

            img = new BufferedImage((int) Math.round(width), (int) Math.round(height), BufferedImage.TYPE_INT_ARGB);
            Graphics2D g2d = img.createGraphics();
            g2d.setColor(Color.RED);
            g2d.draw(new Rectangle2D.Double(0, 0, width - 1, height - 1));
            g2d.draw(new Line2D.Double(0, 0, width, height));
            g2d.draw(new Line2D.Double(0, height, width, 0));
            g2d.dispose();
        }

        @Override
        public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException {
            int result = NO_SUCH_PAGE;
            if (pageIndex < 2) {
                Graphics2D g2d = (Graphics2D) graphics;
                double width = pageFormat.getImageableWidth();
                double height = pageFormat.getImageableHeight();

                System.out.println("Page width = " + width + " = " + pixelsToCms(width, 72));
                System.out.println("Page height = " + height + " = " + pixelsToCms(height, 72));

                g2d.translate((int) pageFormat.getImageableX(),
                                (int) pageFormat.getImageableY());
                double x = cmsToPixel(1, 72);
                double y = cmsToPixel(1, 72);
                System.out.println("Draw At " + x + "x" + y);
                g2d.drawRect(0, 0, (int)width - 1, (int)height - 1);
                g2d.drawImage(img, (int)x, (int)y, null);
                result = PAGE_EXISTS;
            }
            return result;
        }

    }
}


 类似资料:
  • 问题内容: 我必须在热蓝牙打印机上打印一些数据,我正在这样做: 它适用于文本,但不适用于图像。我想我需要获取byte[]图像数据。我尝试通过这种方式获取图像数据: 不幸的是,打印机打印了许多奇怪的字符(大约50厘米的纸张)。我不知道如何打印图像。 我想尝试获取位图的像素,然后将其转换为a byte[]并发送,但是我不知道该怎么做。 谢谢 更新: 经过这么长时间,我正在执行此操作:我有一个名为pri

  • 我在标签打印机上打印时遇到了问题。下面的代码在一个上打印4个“标签”(附标签图片)。 下面的代码打印到兄弟QL-500标签打印机上。它打印到3.5"乘1.1"标签上。 如果有人能帮我更好地理解代码,那也太好了。 下面是它打印的内容:

  • 问题内容: 使用Java,我需要在未本地安装的网络打印机上进行打印。我只知道打印机名称。我看过的所有教程都以类似以下内容开始: 问题是可能没有安装打印机,因此在这种情况下服务将为空。我需要直接设置打印机名称,而不仅仅是通过可见的打印机枚举。 问题答案: 如果Java AWT Printing未向运行打印应用程序的Windows / Active Directory用户注册,则无法通过路径找到打印机

  • 问题内容: 我只想在不选择用户的情况下打印JasperReport。我进行了搜索,但是没有有效的解决方案。这是我的代码的相关部分: 我想选择一台打印机,而不是简单的printReport。有什么办法吗? 问题答案: 这是应该的样子:

  • 问题内容: 当前正在检索机器上安装的默认打印机以进行打印。我希望能够选择文档要使用的打印机。最好的方法是什么? 码: 问题答案: 在下面创建类,将其导入,然后在知道打印机名称的情况下尝试调用;如果您不知道可以访问哪些打印机,请调用一个包含所有可行的注册打印机名称的。 也可以查看我对这个SO问题的答案以获取更多详细信息:

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