Печать на Java выше 72 DPI не заполняет страницу - PullRequest
0 голосов
/ 20 декабря 2011

Я пишу приложение jOGL, которое позволяет пользователю распечатать скриншот текущего рендера.Чтобы распечатать визуализацию, я устанавливаю размер контекста OpenGL для области печати на бумаге, а затем сохраняю передний буфер в изображение, которое рисуется на холсте для печати. ​​

Приложение также должно распечататьэти снимки экрана с максимально возможным качеством, поэтому я пытался увеличить DPI с 72 по умолчанию до 300. Однако вместо увеличения разрешения изображения оно остается прежним и только теперь заполняется примерно на 1/4страница.Любая идея, почему это происходит?

Вот код печати:

    // Set up for printing
    PrinterJob job = PrinterJob.getPrinterJob();

    PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
    PrinterResolution pr =
      new PrinterResolution(300, 300, PrinterResolution.DPI);

    aset.add(pr);

    aset.add(PrintQuality.HIGH);

    boolean ok = job.printDialog(aset);
    if (ok) {
        try {
            Book book = new Book();

            PageFormat pf = job.getPageFormat(aset);
            Paper paper = pf.getPaper();

            // Halve margins
            paper.setImageableArea(pf.getImageableX()/2, pf.getImageableY()/2, pf.getImageableWidth() + pf.getImageableX(), pf.getImageableHeight() + pf.getImageableY());
            pf.setOrientation(PageFormat.LANDSCAPE);

            pf.setPaper(paper);

            book.append(glcanvas, pf, 2);

            job.setPageable(book);
            job.print(aset);
        }
    }

Затем, в моем печатном объекте, я изменяю размер контекста OpenGL:

    glcanvas.reshape(0, 0, (int)pf.getImageableWidth(), (int) pf.getImageableHeight() - StaticViewerUtility.HEADER_HEIGHT);

Однако, воображаемый размер PageFormat никогда не меняется.Он остается на 72, 72, 468, 648 (это 72 DPI с полями 1 "на бумаге 8,5" x11 "). Даже при DPI, установленном на 300, область изображения не меняется. Повышение этого значения только заставляет принтер видетьстраница в произвольном размере (например: 22.87232 "x11.8892"), и изображение по-прежнему распечатывается только в углу страницы. Я также пытался вручную изменить размер контекста OpenGL, но распечатка по-прежнемуобрезать по точным размерам, которые были изначально.

Пример снимка экрана проблемы: http://img32.imageshack.us/img32/2708/capturedodg.jpg

Есть что-то, что я пропускаю?

1 Ответ

2 голосов
/ 20 декабря 2011

, поэтому я пытался увеличить DPI с 72 по умолчанию до 300

OpenGL создает растровое изображение, что означает, что у вас фиксированное количество пикселей. Разрешение (DPI) сообщает принтеру, сколько пикселей на дюйм. Если вы увеличите DPI, фиксированное количество пикселей будет покрывать только более короткую длину. Чтобы компенсировать это, вам нужно рендерить с OpenGL с соответственно более высоким разрешением.

У фотографирования из окна есть свои проблемы. Я настоятельно рекомендую использовать внеэкранный буфер, такой как PBuffer или Frame Buffer Object.


OpenGL, будучи растеризатором, предназначенным для графики в реальном времени, в любом случае не подходит для печати принтеров (принтеры любят векторную графику как ввод данных, но вывод OpenGL - это растровое изображение).

Обычно используется метод высококачественной печати с использованием OpenGL:

  • Определите целевой размер и разрешение изображения. Например. 10 дюймов × 20 дюймов при 300 точек на дюйм. Таким образом, требуемое разрешение составляет 3000 × 6000 пикселей.

  • Существует максимальный размер для кадровых буферов; OpenGL требует как минимум 4096 × 4096 поддержки. С такими функциями, как EyeFinity, вы получаете десятки тысяч пикселей. Но допустим, что ваша реализация может иметь дело только с 4096 × 4096 макс. Таким образом, вы не можете вписать 3000 × 6000 в нем. Решение плиточного рендеринга. Вы делите свою картинку на 2 × 3000 × 3000

    for t in tiles:
        glViewport(0, 0, t.width, t.height)
        glMatrixMode(GL_PROJECTION)
        glScalef(total_width / t.width, total_height / t.height, 1)
        glTranslatef(-1 + 2*total_width / t.off_x, -1 + 2*total_height / t.off_y, 0)
        your_projection()
        render_scene()
    

    Затем объедините плитки в большую картинку.

Еще один приятный метод - перевод OpenGL в векторный вывод: http://geuz.org/gl2ps/ (к сожалению, эта библиотека, похоже, поддерживает только немедленный режим). Если вы все еще хотите использовать графический процессор и использовать современные функции, вы также можете использовать обратную связь преобразования.

...