2012-02-27 24 views
5

JavaDocs chỉ ra rằng GraphicsEnvironment hỗ trợ "thiết bị màn hình và máy in".Lấy Java Printer GraphicsDevice

Tôi có thể xem cách lấy thông tin về thiết bị màn hình, nhưng dường như tôi không thể tìm hiểu thông tin về cách lấy thông tin về Thiết bị Máy in.

Về cơ bản, khi in, tôi muốn có thể tạo một hình ảnh đệm tương thích bằng cách sử dụng các thiết bị GraphicsConfiguration.

Những lý do chính vì muốn làm điều này là:

  1. Chúng tôi muốn để đệm một yêu cầu trang theo yêu cầu đầu tiên của trang và chỉ cần sơn lại bộ đệm trên yêu cầu tiếp theo của trang (như trang chứa một số hình ảnh và một số hiển thị phức tạp - thay vì sau đó lãng phí thời gian vẽ mỗi yêu cầu trang, chúng tôi muốn sử dụng bộ đệm)
  2. Duy trì độ phân giải cao của máy in. Chúng tôi đã thấy rằng nếu chúng ta vẽ trực tiếp cho bối cảnh đồ họa của máy in, chúng tôi có được kết quả quan trọng cao hơn sau đó chúng tôi thực hiện nếu chúng tôi thử và sử dụng hình ảnh có đệm có cùng kích thước.

Tôi đã thử tìm kiếm JavaDocs và Google mà không gặp may.

Mọi đề xuất ??

Cheers

cập nhật dựa trên ý tưởng bổ sung

Dựa trên ý tưởng bổ sung, nó đã được đề nghị thử sử dụng một cái gì đó giống như ...

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: 

Mà không thực sự tạo ra một BufferedImage sẽ được dịch sang máy in DPI

Để kiểm tra ing dễ dàng hơn, tôi đã viết một phương pháp đơn giản 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); 
} 

nào tôi có thể sử dụng một trong hai máy in Graphics bối cảnh hoặc Graphics bối cảnh khác.

Bây giờ hiển nhiên, khi in đến trang A4 @ 72dpi, kích thước hình ảnh kết quả là 595x841, ở mức 600dpi (đã được báo cáo bằng ví dụ trên), kết quả là hình ảnh có kích thước 4970x7029. Được rồi, đây là tốt, tôi sẽ chỉ cần kích thước hình ảnh khi vẽ đến máy in mục tiêu Graphics bối cảnh sử dụng một cái gì đó giống như ...

g2d.drawImage(buffer, 0, 0, (int) pageFormat.getImageableWidth(), (int) pageFormat.getImageableWidth(), null); 

(Đây là thử nghiệm, do đó, không nhảy vào tôi về chất lượng liên quan đến vấn đề chỉ được nêu ra) ...

Printing

(Bình thường ở bên trái, BufferedImage ở bên phải) ... okay, điều đó sẽ không làm

Vì vậy, tôi thì nghĩ, tôi có thể áp dụng thang tỷ lệ AffineTransform với bối cảnh Graphics vùng đệm, sử dụng một cái gì đó như ...

double scale = dpi/72d; 
AffineTransform scaleAT = AffineTransform.getScaleInstance(scale, scale); 
g2d.setTransform(scaleAT); 
print(g2d, pageFormat.getImageableWidth(), pageFormat.getImageableWidth()); 

Điều này sẽ có nghĩa là tôi sẽ không cần phải áp dụng bất kỳ dịch "in chế độ" loại trong thói quen sơn cơ bản hiện có, chúng tôi có ...

Điều này dẫn đến ...

Not quite

Nhưng đợi một phút, có gì sai ở đây?

Vì vậy, tôi quay trở lại và đã xem xét tất cả các phép đo ...

GraphicsConfiguration conf = ((Graphics2D) graphics).getDeviceConfiguration(); 
//... 
Rectangle bounds = conf.getBounds(); 
buffer = conf.createCompatibleImage(bounds.width, bounds.height); 

Đã được báo cáo một kích thước hình ảnh của 4960x7015, nhưng nó phải là 4970x7029 ... nhưng chờ đợi, những gì về khu vực có thể tưởng tượng ... tại 600dpi nó phải là, 3768x5827 ... để không thể dựa vào.

Ngay cả sau khi sửa chữa cho điều này, kết quả vẫn không có hình ảnh xếp hàng với mong đợi ở một trong hai vị trí cũng không chất lượng ...

Still misaligned...

+0

kích thước này của câu hỏi này là Java Graphics2D hoặc đầu ra cho máy in HW ??? – mKorbel

+1

@mKorbel không thực sự. Cũng giống như bạn có thể tạo một hình ảnh tương thích để hiển thị trên màn hình, tôi muốn thực hiện tương tự với máy in. Về mặt lý thuyết, nếu bạn tạo một ảnh đệm và vẽ nó vào ngữ cảnh đồ họa của máy in, nó sẽ hiển thị tại (tôi nghĩ) 72dpi. Trường hợp như bạn vẽ trực tiếp đồ thị, bạn có được dpi của máy in – MadProgrammer

+0

cảm ơn, aaaach bây giờ là câu hỏi rõ ràng đối với tôi :-) – mKorbel

Trả lời

0

Graphics2D cung cấp một phương pháp để có được một GraphicsConfiguration đó là được liên kết với GraphicsDevice. Thông tin thiếu là thông tin, khi bạn có thể giả định rằng GraphicsGraphics2D trong ngữ cảnh in.

Ví dụ: chương trình sau hoạt động trong thiết lập của tôi:

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

Tôi đã thử nó và nó không hoạt động. Tôi sẽ thử lại để chắc chắn – MadProgrammer

+0

Thực ra, tôi đã thử một vài thứ tương tự cách đây vài tháng mà không thành công. Vẫn đang thử nghiệm – MadProgrammer

+0

Vì vậy, để hoàn thành, nó hoạt động trên 'Windows 7 32Bit',' jdk 1.7.0_40'… – Holger

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