如何在java中设计要在300 dpi打印机上打印的图像 [英] How to design an image in java to be printed on a 300 dpi printer

查看:103
本文介绍了如何在java中设计要在300 dpi打印机上打印的图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想用Java制作图像并将其打印在尺寸为150 x 100 mm的标签上的300dpi标签打印机上。
如何制作图像以便在位置(10,10)(毫米)处准确打印一条线(或任何类型的元素),并且该线在位置(10,50)处结束? / p>

换句话说:我的挑战不是如何制作一条线(我正在使用Graphics2D,bufferedImage),但它是如何能够准确地告诉这条线的位置必须是(以毫米为单位)标签。



任何想法?

解决方案

Java的print API基本上假设一切都是在72 dpi完成的。这意味着您可以将其用作转换为不同测量值的基础...



这只是意味着您需要并启动值和目标测量...

  //每英寸的CM数量
公共静态最终双倍CM_PER_INCH = 0.393700787d;
//每CM的英寸数
公共静态最终双INCH_PER_CM = 2.545d;
//每毫米
公共静态最终双倍INCH_PER_MM = 25.45d的英寸数;

/ **
*根据提供的DPI
* @param像素将给定像素转换为cm。
* @param dpi
* @return
* /
public static double pixelsToCms(double pixels,double dpi){
return inchesToCms(pixels / dpi);
}

/ **
*根据提供的DPI将给定的cm转换为像素
* @param cms
* @param dpi
* @return
* /
public static double cmsToPixel(double cms,double dpi){
return cmToInches(cms)* dpi;
}

/ **
*将给定的厘米转换为英寸
* @param cms
* @return
* /
public static double cmToInches(double cms){
return cms * CM_PER_INCH;
}

/ **
*将给定的英寸转换为cm的
* @param英寸
* @return
* /
public static double inchesToCms(双英寸){
返回英寸* INCH_PER_CM;
}

因此,为了以10mmx10mm打印图像,您需要转换这个像素的每英寸

  double point = cmsToPixel(1,72); 

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



对于某些例子......




  • 使图像适合打印区域

  • < a href =https://stackoverflow.com/questions/14725456/fitting-printerjob-object-to-specific-print-format-of-bufferedimage/14726386#14726386>将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));

打印时,我的可打印已通过可成像面积为425.20 x 283.46像素,相当于15.03 x 10.02 cm @ 72dpi(粗略)。这就是Java的工作原理,它的基本打印API一直在假设72dpi。



所以。如果我准备一张10 x 50 mm @ 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;

公共类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();
}
}
}
});
}

//每英寸的CM数量
公共静态最终双倍CM_PER_INCH = 0.393700787d;
//每CM的英寸数
公共静态最终双INCH_PER_CM = 2.545d;
//每毫米
公共静态最终双倍INCH_PER_MM = 25.45d的英寸数;

/ **
*根据提供的DPI
*
* @param像素将给定像素转换为cm's
* @param dpi
* @return
* /
public static double pixelsToCms(double pixels,double dpi){
return inchesToCms(pixels / dpi);
}

/ **
*根据提供的DPI将给定的cm转换为像素
*
* @param cms
* @param dpi
* @return
* /
public static double cmsToPixel(double cms,double dpi){
return cmToInches(cms)* dpi;
}

/ **
*将给定的厘米转换为英寸
*
* @param cms
* @return
* /
public static double cmToInches(double cms){
return cms * CM_PER_INCH;
}

/ **
*将给定的英寸转换为cm的
*
* @param inch
* @return
* /
公共静态双英寸TOCms(双英寸){
返回英寸* INCH_PER_CM;
}

公共静态类PrintTask实现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(图形图形,PageFormat pageFormat,int pageIndex)抛出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;
}
返回结果;
}

}
}


I want to make an image in Java and print it on a 300dpi label printer on a label, sized 150 x 100 mm. How can I make the image so that a line (or whatever kind of element) is printed exactly at position (10,10) (in millimeters), and that line is ended at position (10,50)?

In other words: My challenge is not how to make a line (I'm using Graphics2D, bufferedImage), but it is how to be able to tell exactly where this line has to be (in millimeters) on the label.

Any Ideas?

解决方案

Java's print API basically works on the assumption that everything is done at 72 dpi. This means that you can use this as bases for converting to/from different measurements...

This just means you need and start value and target measurement...

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

So, in order to print the image at 10mmx10mm, you would need to convert this to pixel's per inch

double point = cmsToPixel(1, 72);

You're probably also going to need to think about maybe downsizing the image to fit into the printable area.

For some examples...

Update with test results

So I did some tests (code to follow)...

First, I set up a PrintRequestAttributeSet to request only print services capable of supporting 300x300 dpi...

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

When printed, my Printable was passed an imageable area of 425.20 x 283.46 pixels, which equates to 15.03 x 10.02 cm @ 72dpi (roughly). This is how Java works, it's basic print API has always worked on the assumption of 72dpi.

So. If I prepare an image of 10 x 50 mm @ 72 DPI, I get an image size of 28.346 x 141.732 pixels, which will easily fit within the imageable area (of 425.20 x 283.46).

However, if I use 300 dpi, I get a image size of 118.11 x 590.551 pixels, which is going to run us into trouble, requiring us to downscale the image...

This, actually, may be desirable, you will have to perform some testing to find out.

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

    }
}

这篇关于如何在java中设计要在300 dpi打印机上打印的图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆