2012-02-27 5 views
5

W Javadocs wskazują, że GraphicsEnvironment obsługuje „ekranem i drukarki urządzenia”.Get GraphicsDevice drukarki Drukarka Java

widzę, w jaki sposób uzyskać informacje na temat urządzeń z ekranem, ale nie wydaje się być w stanie uzyskać informacje dotyczące sposobu uzyskiwania informaiton o urządzenie drukujące.

Zasadniczo podczas drukowania, chcę być w stanie stworzyć zgodną buforowany obraz jest za pomocą GraphicsConfiguration urządzeń.

Głównymi powodami chcąc to zrobić:

  1. Chcemy bufor żądanie strony na pierwsze żądanie strony i po prostu malować z powrotem bufor na kolejne żądania strony (jako strona zawiera szereg obrazów i trochę skomplikowany renderowania - a następnie tracić czas malowania każdy wniosek strony, chcemy wykorzystać bufor)
  2. utrzymać wysoką rozdzielczość wyjściową drukarki. Odkryliśmy, że jeśli malujemy bezpośrednio do kontekstu grafiki drukarek, uzyskujemy istotnie wyższy wynik ilościowy niż wtedy, gdy spróbujemy użyć buforowanego obrazu o tym samym rozmiarze.

Próbowałem przeszukiwać JavaDocs i Google bez powodzenia.

Jakieś sugestie?

Cheers

Zaktualizowany na podstawie dodatkowych pomysłów

podstawie dodatkowych pomysłów, zasugerowano, aby wypróbować coś takiego ...

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: 

Który ma faktycznie generują BufferedImage które byłyby tłumaczone na DPI drukarek

zrobić test ing łatwiejsze, napisałem prostą metodę 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); 
} 

Który mogłem użytkownik albo drukarka Graphics kontekst lub inny kontekst Graphics.

teraz oczywiste, podczas drukowania na stronę A4 @ 72dpi, otrzymany rozmiar obrazu to 595x841, przy 600 dpi (który został zgłoszony przez powyższym przykładzie), skutkuje obrazem 4970x7029. Dobra, to jest w porządku, ja tylko trzeba skalować obraz podczas rysowania do drukarki docelowej Graphics kontekście użyciu coś jak ...

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

(To jest test, więc nie skakać na mnie o kwestie związane z jeszcze) jakość ...

Printing

(Normal po lewej stronie, BufferedImage po prawej) ... Dobrze, że nie zrobi

Więc potem myślałem, że może zastosować skalę AffineTransform do kontekstu bufora Graphics, używając czegoś takiego jak ...

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

Oznaczałoby to, że nie trzeba stosować żadnych tłumaczenia „print mode” typ ciągu bazowego istniejących procedur malarskich mamy ...

Spowodowało ...

Not quite

Ale poczekaj chwilę, co tu jest nie tak?

Wróciłem więc i miał obejrzenia wszystkich pomiarów ...

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

Czy zgłoszenie rozmiar obrazu 4960x7015, ale powinno być 4970x7029 ... ale zaraz, co można sobie wyobrazić okolicy ... przy 600dpi powinno być, 3768x5827 ... więc nie można na nim polegać.

Nawet po skorygowaniu o to, wynik nadal nie ma wizerunek wyciągający z oczekiwaniami w każdym położeniu ani jakości ...

Still misaligned...

+0

To pytanie dotyczy rozmiaru przychodzi Java Graphics2D lub wyjście do HW Printers ??? – mKorbel

+1

@mKorbel ani tak naprawdę. Podobnie jak możesz stworzyć zgodny obraz do renderowania na ekranie, chcę zrobić to samo z drukarką. Zasadniczo, jeśli utworzysz buforowany obraz i narysujesz go w kontekście graficznym drukarki, renderuje się na poziomie (jak sądzę) 72dpi. Gdzie tak jakbyś rysował bezpośrednio na wykresach, zyskujesz rozdzielczość drukarki dzięki – MadProgrammer

+0

dzięki, aaaach teraz jest dla mnie jasne :-) – mKorbel

Odpowiedz

0

Graphics2D zapewnia sposób, aby uzyskać GraphicsConfiguration który jest połączony z GraphicsDevice. Brakuje informacji, kiedy można bezpiecznie założyć, że Graphics jest Graphics2D w kontekście drukowania.

E.g. w moim setupie działa następujący program:

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

Utykam Próbowałem tego i to nie działało. Będę ponownie sprawdzać, aby się upewnić, – MadProgrammer

+0

Właściwie próbowałem czegoś podobnego kilka miesięcy temu bez powodzenia. Wciąż testowałem – MadProgrammer

+0

Tak więc pod względem kompletności działało to na 'Windows 7 32Bit',' jdk 1.7.0_40' ... – Holger