Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8191800

Rotated BufferedImage rendered blank only when printing

XMLWordPrintable

    • 2d
    • x86_64
    • windows_7

      FULL PRODUCT VERSION :
      java version "10-ea"
      Java(TM) SE Runtime Environment (build 10-ea+30)
      Java HotSpot(TM) 64-Bit Server VM (build 10-ea+30, mixed mode)


      ADDITIONAL OS VERSION INFORMATION :
      Microsoft Windows [Version 6.1.7601]

      A DESCRIPTION OF THE PROBLEM :
      The barcode-like image appears blank when drawn on a printing graphics device but not when drawn on a BufferedImage graphics device.

      When changing the image so that it is black (by commenting the line with "img.setRGB"), then it appears at the correct position.

      This happens also on jdk7.0.80, 8.0.151 and 9.0.1.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      run the code
      see the print dialog
      choose a printer (can be a real printer, or a virtual printer like xps)
      press OK
      look at the file output.png in the local directory and the printed output


      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      I expected the barcode-like image to appear within the rectangle both in the png file and in print.
      ACTUAL -
      The barcode-like image appears within the rectangle only in the png file but not in print.

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import java.awt.Color;
      import java.awt.Graphics;
      import java.awt.Graphics2D;
      import java.awt.geom.AffineTransform;
      import java.awt.image.BufferedImage;
      import java.awt.print.PageFormat;
      import java.awt.print.Printable;
      import java.awt.print.PrinterException;
      import java.awt.print.PrinterJob;
      import java.io.File;
      import java.io.IOException;
      import javax.imageio.ImageIO;

      /**
       * @author Tilman Hausherr
       */
      public class PDFBox4010 implements Printable
      {
          public static void main(String[] args) throws IOException, PrinterException
          {
              new PDFBox4010().doStuff();
          }

          /**
           * Does the same graphics operations on the graphics device of an image and of a printer.
           * Both should have the same output but only the image is OK, i.e. shows a barcode-line
           * image within a border. The printer output only shows the border.
           *
           * @throws IOException
           * @throws PrinterException
           */
          void doStuff() throws IOException, PrinterException
          {
              PrinterJob job = PrinterJob.getPrinterJob();
              int width = (int) job.defaultPage().getWidth();
              int height = (int) job.defaultPage().getHeight();

              BufferedImage targetImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
              Graphics2D g = (Graphics2D) targetImage.getGraphics();

              renderStuff(g, targetImage.getWidth(), targetImage.getHeight());

              g.dispose();

              ImageIO.write(targetImage, "png", new File("output.png"));

              job.setPrintable(this);
              if (job.printDialog())
              {
                  // this will call renderStuff() again
                  job.print();
              }
          }

          /**
           * Draws a rotated one-line image into a graphics device.
           * @param g
           * @param width
           * @param height
           */
          public void renderStuff(Graphics2D g, int width, int height)
          {
              // background
              g.setBackground(Color.white);
              g.clearRect(0, 0, width, height);

              BufferedImage img = new BufferedImage(303, 1, BufferedImage.TYPE_BYTE_BINARY);

              // barcode-like pattern on single pixel line
              for (int i = 0; i < img.getWidth(); ++i)
              {
                  img.setRGB(i, 0, (i / 2 % 3) == 0 ? 0 : 0xFFFFFF);
              }

              AffineTransform at = new AffineTransform(0, -0.36, -63, 0, 163, 300);

              // draw our "barcode"
              g.drawImage(img, at, null);

              // draw rectangle around "barcode"
              g.setColor(Color.red);
              g.drawRect(100, 191, 63, 109);
          }

          @Override
          public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException
          {
              if (pageIndex != 0)
              {
                  return NO_SUCH_PAGE;
              }
              renderStuff((Graphics2D) graphics, (int) pageFormat.getWidth(), (int) pageFormat.getHeight());
              return PAGE_EXISTS;
          }
      }

      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Do all graphics operations first on a big BufferedImage and then draw that one. This is very inefficient.

            psadhukhan Prasanta Sadhukhan
            webbuggrp Webbug Group
            Votes:
            1 Vote for this issue
            Watchers:
            6 Start watching this issue

              Created:
              Updated: