2013-09-24 56 views
8

Tôi muốn tạo một hình ảnh bằng Java và in trên máy in nhãn 300dpi trên nhãn, có kích thước 150 x 100 mm. Làm cách nào để tạo hình ảnh sao cho dòng (hoặc bất kỳ loại phần tử nào) được in chính xác ở vị trí (10,10) (tính bằng milimét) và dòng đó được kết thúc ở vị trí (10,50)?Cách thiết kế hình ảnh trong java được in trên máy in 300 dpi

Nói cách khác: Thách thức của tôi không phải là cách tạo dòng (tôi đang sử dụng Graphics2D, bufferedImage), nhưng đó là cách để có thể biết chính xác vị trí của đường này (tính bằng milimét) trên nhãn .

Bất kỳ ý tưởng nào?

+1

Nói chung, in được thực hiện ở 72 dpi (được, không phải vậy, nhưng API cho rằng đó là). Vì vậy, bắt đầu bằng cách cố gắng không phải lo lắng về 300dpi và tập trung vào chuyển đổi từ 72 dpi đến những gì bạn cần – MadProgrammer

Trả lời

5

API in của Java về cơ bản hoạt động trên giả định rằng mọi thứ được thực hiện ở 72 dpi. Điều này có nghĩa rằng bạn có thể sử dụng làm cơ sở để chuyển đổi đến/từ các phép đo khác nhau ...

này chỉ có nghĩa là bạn cần và giá trị đầu và đo lường mục tiêu ...

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

Vì vậy, để in hình ảnh ở 10mmx10mm, bạn sẽ cần phải chuyển đổi này để của pixel mỗi inch

double point = cmsToPixel(1, 72); 

bạn đang có lẽ cũng sẽ cần phải suy nghĩ về lẽ giảm kích thước ảnh để phù hợp với khu vực có thể in được.

Đối với một số ví dụ ...

Cập nhật với kiểm tra kết quả

Vì vậy, tôi đã làm một số xét nghiệm (code để làm theo) ...

Trước tiên, tôi thiết lập một PrintRequestAttributeSet để yêu cầu duy nhất dịch vụ in khả năng hỗ trợ 300x300 dpi ...

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

Khi in, tôi Printable đã được thông qua một khu vực imageable của 425,20 x 283,46 pixel, tương đương với 15,03 x 10,02 cm @ 72dpi (gần). Đây là cách Java hoạt động, đó là API in cơ bản luôn làm việc với giả định 72dpi.

So. Nếu tôi chuẩn bị hình ảnh có kích thước 10 x 50 mm @ 72 DPI, tôi nhận được kích thước hình ảnh là 28.346 x 141.732 pixel, điều này sẽ dễ dàng vừa với khu vực có thể tưởng tượng (425.20 x 283.46).

Tuy nhiên, nếu tôi sử dụng 300 dpi, tôi nhận được một kích thước hình ảnh của 118,11 x 590,551 pixel, mà sẽ chạy chúng tôi vào rắc rối, đòi hỏi chúng ta phải thu hẹp hình ảnh ...

này, trên thực tế, có thể được mong muốn, bạn sẽ phải thực hiện một số thử nghiệm để tìm hiểu.

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

    } 
} 
-1

Có rất nhiều điều cần xem xét, hầu hết trong số đó là toán cơ bản. Tôi không quen thuộc với Java2D, vì vậy tôi không thể cho bạn biết nếu có bất kỳ chức năng trợ giúp nào, nhưng đây là toán:

150 x 100 mm là khoảng 6x4 inch.Tại 300 DPI, bạn cần độ phân giải pixel là 1800x1200.

1" tương đương với 300 Pixels, và tương đương với 25,4 mm này có nghĩa là s mà 1 mm là tương đương với khoảng 12 pixel (11.8).

Vì vậy, nếu bạn muốn thực hiện một dòng bắt đầu từ 10x10mm, bạn cần nhân với số lượng pixel bằng mm, trong trường hợp này 12. Vì vậy, bắt đầu vẽ đường của bạn ở 120x120 pixel.

Tương tự như vậy nếu bạn cần kết thúc dòng ở 10x50mm, bạn cần phải kết thúc vẽ tại 1202600.

Toán học là khác nhau trong mỗi trường hợp, tùy thuộc vào độ phân giải của máy in, nhưng đối với câu hỏi được hỏi, các số này nên đủ rồi.

Hy vọng điều đó sẽ hữu ích.

Các vấn đề liên quan