Получить Java Printer GraphicsDevice - PullRequest
5 голосов
/ 28 февраля 2012

JavaDocs указывают, что GraphicsEnvironment поддерживает «устройства экрана и принтера».

Я могу видеть, как получить информацию об устройствах экрана, но я не могу найти информацию о том, какполучить информацию об устройстве принтера.

По сути, при печати я хочу иметь возможность создавать совместимое буферизованное изображение с помощью устройств GraphicsConfiguration.

Основными причинами для этого является:

  1. Мы хотим буферизовать запрос страницы по первому запросу страницы и просто перерисовать буфер при последующих запросах страницы (так как страница содержит несколько изображений и некоторые сложные визуализации -вместо того, чтобы тратить время на рисование каждого запроса страницы, мы хотим использовать буфер)
  2. Поддерживать вывод принтера с высоким разрешением.Мы обнаружили, что если мы рисуем непосредственно в графическом контексте принтеров, мы получаем значительно более высокий выходной результат, чем если бы мы попытались использовать буферизованное изображение того же размера.

Я пыталсяпоиск JavaDocs и Google без удачи.

Любые предложения ??

Приветствия

Обновлено на основе дополнительных идей

На основеВ качестве дополнительных идей было предложено попытаться использовать что-то вроде ...

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:

, которое фактически генерирует BufferedImage, которое будет переведено на принтеры DPI

, чтобы упростить тестирование, Я написал простой 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);
}

, который я мог бы использовать либо в контексте принтера Graphics, либо в другом Graphics контексте.

Теперь очевидно, что при печатина странице A4 при 72dpi результирующий размер изображения составляет 595x841, при 600dpi (о чем сообщалось в приведенном выше примере), в результате получается изображение 4970x7029.Ладно, это нормально, мне нужно будет только уменьшать изображение при рисовании на целевой принтер Graphics в контексте, используя что-то вроде ...

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

(Это тест, так что непоспешите поговорить о проблемах, связанных с качеством) ...

Printing

(Обычный слева, BufferedImage справа) ... хорошо, это не будетdo

Итак, я тогда подумал, что мог бы применить масштаб AffineTransform к контексту буфера Graphics, используя что-то вроде ...

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

Это означало бы, что я бы не сталне нужно применять любые переводы типа «режим печати» в рамках существующих существующих процедур рисования ...

Это привело к ...

Not quite

Ноподожди минутку, что здесь не так?

Так что я вернулся и посмотрел на все измерения ...

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

Сообщал размер изображения 4960x7015, но он долженбыть 4970x7029 ... но подождите, как насчет воображаемой области ... при 600dpi это должно быть, 3768x5827 ... так что на это нельзя положиться.

Даже после исправлениядля этого у результата все еще нет соответствия изображения ожиданиям ни по положению, ни по качеству ...

Still misaligned...

1 Ответ

0 голосов
/ 11 сентября 2014

Graphics2D предоставляет метод для получения GraphicsConfiguration, который связан с GraphicsDevice.Отсутствует информация, когда вы можете смело предположить, что Graphics - это Graphics2D в контексте печати. ​​

Например, в моей настройке работает следующая программа:

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;
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...