2012-02-27 8 views
5

I JavaDocs indicano che GraphicsEnvironment supporta "dispositivi dello schermo e della stampante".Ottieni Java Printer GraphicsDevice

Vedo come ottenere informazioni sui dispositivi dello schermo, ma non riesco a trovare informazioni su come ottenere informazioni su un dispositivo stampante.

Fondamentalmente, durante la stampa, voglio essere in grado di creare un'immagine bufferizzata compatibile utilizzando i dispositivi GraphicsConfiguration.

Le principali ragioni per voler fare questo è:

  1. Vogliamo per tamponare una richiesta di pagina alla prima richiesta della pagina e semplicemente dipingere di nuovo il buffer sulle successive richieste della pagina (come pagina contiene un numero di immagini e alcuni rendering complessi - piuttosto che perdere tempo a dipingere ogni richiesta di pagina, vogliamo usare un buffer)
  2. Mantenere l'output ad alta risoluzione della stampante. Abbiamo scoperto che se dipingiamo direttamente nel contesto grafico delle stampanti, otteniamo un output di quanity sostanzialmente più alto di quello che facciamo se proviamo e usiamo un'immagine bufferizzata della stessa dimensione.

Ho provato a cercare JavaDocs e Google senza fortuna.

Qualche suggerimento ??

Acclamazioni

aggiornamento sulla base di ulteriori idee

Sulla base di ulteriori idee, è stato suggerito di provare a utilizzare qualcosa di simile ...

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: 

che fa in realtà generare un BufferedImage che verrebbe tradotto nelle stampanti DPI

Per eseguire il test ing più facile, ho scritto un semplice metodo di 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); 
} 

quale potevo utente sia la stampante Graphics contesto o altro Graphics contesto.

Ora ovvio, quando si stampa su una pagina A4 a 72 dpi, la dimensione dell'immagine risultante è 595x841, a 600 dpi (che è stata riportata nell'esempio sopra), si ottiene un'immagine di 4970x7029. Va bene, questo va bene, sarò solo bisogno di scalare l'immagine verso il basso quando si disegna per la stampante di destinazione Graphics contesto utilizzando qualcosa di simile ...

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

(Questo è di prova, in modo da non saltare su di me su qualità questioni connesse appena ancora) ...

Printing

(normale a sinistra, BufferedImage a destra) ... va bene, che non farà

Così, allora ho pensato, ho potrebbe applicare una scala AffineTransform nel contesto del buffer Graphics, usando qualcosa come ...

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

Questo vorrebbe dire non avrei bisogno di applicare eventuali traduzioni "modalità di stampa" di tipo all'interno delle routine di vernice sottostanti esistenti che abbiamo ...

Ciò ha provocato ...

Not quite

Ma aspetta un attimo, cosa c'è che non va?

così sono tornato e aveva uno sguardo a tutte le misure ...

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

riportava una dimensione dell'immagine di 4960x7015, ma dovrebbe essere 4970x7029 ... ma aspetta, per quanto riguarda la zona che si possa immaginare ... a 600 dpi dovrebbe essere, 3768x5827 ... in modo che non si possa fare affidamento su di esso.

Anche dopo la correzione per questo, il risultato ancora non ha l'immagine in fila con le aspettative in entrambe le posizioni né qualità ...

Still misaligned...

+0

questa domanda è circa la dimensione è venuto Java Graphics2D o uscita a HW Printers ??? – mKorbel

+1

@mKorbel neanche veramente. Proprio come è possibile creare un'immagine compatibile per il rendering sullo schermo, voglio fare lo stesso con una stampante. In pratica, se si crea un'immagine bufferizzata e la si disegna nel contesto grafico della stampante, viene eseguito il rendering (credo) di 72 dpi. Dove se si disegna direttamente ai grafici, si ottiene il dpi della stampante – MadProgrammer

+0

grazie, aaaach ora è una domanda chiara per me :-) – mKorbel

risposta

0

Graphics2D fornisce un metodo per ottenere un GraphicsConfiguration che è collegato a GraphicsDevice. Ciò che manca sono le informazioni, quando si può tranquillamente supporre che un Graphics sia un Graphics2D nel contesto della stampa.

E.g. il seguente programma funziona nella mia configurazione:

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

Ho suonato il clacson ho provato questo e non ha funzionato. Effettuerò nuovamente il test per essere sicuro che – MadProgrammer

+0

In realtà, ho provato qualcosa di simile qualche mese fa senza successo. Ancora testando – MadProgrammer

+0

Quindi per completezza, ha funzionato su 'Windows 7 32Bit',' jdk 1.7.0_40' ... – Holger

Problemi correlati