Java - рисование буферизованного изображения в печатном виде по сравнению с рисованием непосредственно в печатном виде приводит к нечетким результатам - PullRequest
0 голосов
/ 05 июля 2019

Я разрабатываю программу на Java для печати некоторых этикеток на листе формата А4. Я хотел бы создать метки в отдельном классе, который возвращает BufferedImage, а затем передать коллекцию BufferedImages другому классу, который реализует интерфейс Printable, который затем разместит их на странице и напечатает их.

Я могу сделать все это, но обнаруживаю, что при рисовании BufferedImage в печатном виде, более тонкие элементы, в частности текст, немного размыты. Если я рисую непосредственно в графическом объекте, предоставляемом Printable, результаты будут намного лучше, но это неудобно для структуры программы.

Я попытался установить подсказки сглаживания для текста и графики, а также попытался нарисовать изображение двойного размера, а затем уменьшить его при рисовании в Printable, но это приводит к худшим результатам.

Ниже приведена тестовая программа, которую я написал, чтобы проиллюстрировать различия. На выходе текст явно размыт, когда я использую BufferedImage того же размера, что и квадрат, нарисованный в Printable, и снова при использовании большего BufferedImage и уменьшенного размера.

    package printerresolutiontest;

    import java.awt.Color;
    import java.awt.Font;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.Image;
    import java.awt.RenderingHints;
    import java.awt.image.BufferedImage;
    import java.awt.print.PageFormat;
    import java.awt.print.Paper;
    import java.awt.print.Printable;
    import java.awt.print.PrinterException;
    import java.awt.print.PrinterJob;

    public class PrinterResolutionTest implements Printable {

        public static void main(String[] args) throws PrinterException {

            PrinterResolutionTest printrestest = new PrinterResolutionTest();

            PrinterJob pj = PrinterJob.getPrinterJob();

            PageFormat pf = pj.defaultPage();
            Paper paper = pf.getPaper();
            paper.setImageableArea(0*72, 0*72, 8.3*72, 11.7*72);
            pf.setPaper(paper);
            pj.setPrintable(printrestest, pf);

            Boolean PRINT_DIALOG_OK = pj.printDialog();
            if (PRINT_DIALOG_OK) {
                pj.print();
            }

        }

        @Override
        public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException {

            Graphics2D g2d = (Graphics2D) graphics;
            BufferedImage img1 = new BufferedImage(144, 144, BufferedImage.TYPE_INT_RGB);
            BufferedImage img2 = new BufferedImage(72, 72, BufferedImage.TYPE_INT_RGB);

            Graphics2D g2d_bigbuf = img1.createGraphics();
            Graphics2D g2d_buf = img2.createGraphics();            

            if (pageIndex > 0) {
                return NO_SUCH_PAGE;
            }

            /*************************
             * Draw directly into the Printable graphics object
             */

            g2d.setColor(Color.RED);
            g2d.fillRect(200, 200, 72, 72);
            g2d.setColor(Color.black);
            g2d.drawString("test", 202, (72/2)+202);

            /*************************
             * Draw the same features
             * into a BufferedImage
             */

            g2d_buf.setColor(Color.RED);
            g2d_buf.fillRect(0, 0, 72, 72);
            g2d_buf.setColor(Color.black);
            g2d_buf.drawString("test", 0, 72/2);

            /*************************
             * Draw a double sized square and 
             * increase font size accordingly
             */

            g2d_bigbuf.setColor(Color.RED);
            g2d_bigbuf.fillRect(0, 0, 144, 144);
            g2d_bigbuf.setColor(Color.black);
            Font currentfont = g2d_bigbuf.getFont();
            Font newfont = currentfont.deriveFont(currentfont.getSize() * 2F);
            g2d_bigbuf.setFont(newfont);
            g2d_bigbuf.drawString("test", 0, 144/2);

            // Draw the regular sided BufferedImage
            g2d.drawImage(img2, 300, 200, null);
            // Draw the larger BufferedImage and scale down by half
            g2d.drawImage(img1.getScaledInstance(72, 72, Image.SCALE_AREA_AVERAGING), 400, 200, null);

            return PAGE_EXISTS;
        }

    }

BufferedImage test PNG Вот тестовый снимок экрана из файла, который я распечатал в PDF, как пример различия. В идеале я хотел бы получить то же качество изображения, используя BufferedImage, что и при рисовании непосредственно в Printable.

1 Ответ

0 голосов
/ 05 июля 2019

Экраны и принтеры очень разные носители. На экране вы обычно имеете низкое разрешение от 72 до 92 точек на дюйм (пикселей на дюйм). Каждый пиксель может иметь огромное количество цветов (24 м и более). На принтере у вас обычно высокое разрешение (до 2540 точек на дюйм), но только между 2 (ч / б) и 6 цветами. Для создания промежуточных цветов принтер использует метод растрирования, например, полутона .

То, как вы создаете BufferedImage , вы сильно склонны к выводу на экран: низкое разрешение, использование промежуточных цветов для сглаживания и т. Д. Результат будет плохим. Кроме того, намерение вашего выхода потеряно. Драйвер принтера видит только карту пикселей. Он не знает, где находится текст, и не может оптимизировать вывод для него.

Для улучшения качества у вас есть в основном два варианта:

  • Если вы печатаете только строки и текст и используете только цвета, которые принтер может создавать без смешивания цветов, вы можете создать BufferedImage , который точно соответствует разрешению и цветам принтера. Это должно дать вам достойное качество.

  • В противном случае нарисуйте непосредственно к Для печати . Тогда намерения ваших операций вывода будут сохранены, и драйвер принтера может обеспечить оптимальное качество. Я уверен, немного подумав, что вы можете реорганизовать свой код так, чтобы у вас все еще была очень поддерживаемая структура.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...