This discussion is archived
2 Replies Latest reply: Feb 29, 2012 7:34 AM by 913191 RSS

printing an image to a printer result in poor quality

913191 Newbie
Currently Being Moderated
Hello,

i have an application from which i want to print an image. The image is loaded as a BufferedImage object. The problem is, when i print the image (to the postscript or to the pdf file), the quality is really poor.
When i'm using some other tools (basically any picture viewer application which can print the image) the result is significantly better.
I know there can be some problems with the DPI vs resolution but i'm not exactly sure how to compute the correct values for printing.
I tried to google and tried some methods, but nothing seems to work as i expected.
Basicaly i just want to print an image (in resolution let's say 3000x2000) to a printer (with DPI for example 600x600).

This is how i create the print job:
    PrintRequestAttributeSet printAttributes = new HashPrintRequestAttributeSet();
    printAttributes.add(PrintQuality.HIGH);
    printAttributes.add(new PrinterResolution(600, 600 PrinterResolution.DPI)); 
    printAttributes.add(new Destination(URI.create("file:/tmp/test.ps")));
    PageFormat pf = printerJob.defaultPage();
    Paper paper = pf.getPaper();
    double xMargin = 0.0;
    double yMargin = 0.0;
    paper.setImageableArea(xMargin, yMargin, paper.getWidth() - 2 * xMargin, paper.getHeight() - 2 * yMargin);
    pf.setPaper(paper);

    // create new Printable for the specified image
    printerJob.setPrintable(PrintableImage.get(image), pf)

    if (printerJob.printDialog(printAttributes)) {
        printerJob.print(printAttributes);
    }
Where <i> image </i> is <i> BufferedImage </i> and <i>PrintableImage.get</i> returns new instance which implements <i>javax.print.Printable</i>
Then the actual print is doing this way (i let the commented code which i tried but didn't work for me)
@Override
public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException {
    if (image == null)
        throw new PrinterException("no image specified to be printed");

    // We have only one page, and 'page' is zero-based
    if (pageIndex > 0) {
        return NO_SUCH_PAGE;
    }

    // tranlate the coordinates (according to the orientations, margins, etc)
    Graphics2D printerGraphics = (Graphics2D) graphics;

    //g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
    //g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    //g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
    
    printerGraphics.translate(pageFormat.getImageableX(), pageFormat.getImageableY());

    // THIS IS A TEST - javax.printing api uses 72 DPI, but we have 600DPI set for the printer
    //AffineTransform at = printerGraphics.getTransform();
    //printerGraphics.scale((double)72 / (double)600, (double)72 / (double)600);
    //printerGraphics.drawRenderedImage(image, null);
    //printerGraphics.setTransform(at);
    //if(printerGraphics != null)
        //return PAGE_EXISTS;
    
    double scale = 72.0 / 600.0;
    
    Dimension pictureSize = new Dimension((int)Math.round(image.getWidth() / scale), (int) Math.round(image.getHeight() / scale));
    
    
    // center the image horizontaly and verticaly on the page
    int xMargin = (int) ((pageFormat.getImageableWidth() - image.getWidth()) / 2);
    int yMargin = (int) ((pageFormat.getImageableHeight() - image.getHeight()) / 2);
    xMargin = yMargin = 0;

    System.out.println(String.format("page size [%.2f x %.2f], picture size [%.2f x %.2f], margins [%d x %d]", pageFormat.getImageableWidth(), pageFormat.getImageableHeight(), pictureSize.getWidth(), pictureSize.getHeight(), xMargin, yMargin));
    
    printerGraphics.drawImage(image, xMargin, yMargin, (int)pageFormat.getWidth(), (int)pageFormat.getHeight(), null);
    
    //printerGraphics.drawImage(image, 0, 0, null);
    //printerGraphics.drawImage(image, xMargin, yMargin, pictureSize.width, pictureSize.height, null);
    //printerGraphics.drawImage(image, xMargin, yMargin, (int) pageFormat.getImageableWidth(), (int) pageFormat.getImageableHeight(), 0, 0, pictureSize.width, pictureSize.height, null);
    //printerGraphics.drawImage(image, 0, 0, (int) pageFormat.getWidth() - xMargin, (int) pageFormat.getHeight() - yMargin, 0, 0, pictureSize.width, pictureSize.height, null);
    
    return PAGE_EXISTS;
}
Does anybody solves the same problem?
Any help would be appreciated.
Thanks
Matej
  • 1. Re: printing an image to a printer result in poor quality
    Maxideon Explorer
    Currently Being Moderated
    A printer setting of 600 dpi doesn't mean 600 pixels per inch. It's a relative quantity of how much ink you want the printer to use to faithfully reproduce the pixels on the page. So for example, you start to achieve photo quality around 250 pixels per inch, but would need to set the printer to 1200+ dpi if you ever hope for it to print out correctly. Trying to achieve 600 pixels per inch would be suicide for your printer.

    That being said, you're not actually doing anything with this dpi or ppi stuff. In your code you're ultimately just drawing the image, scaled to the page's size using nearest neighbor interpolation, and printing it at 72 pixels per inch. In the code you commented out, you have the interpolation fine but miss the mark on the scaling. Specifically, you scale the graphics correctly, but then two lines later you set the transform to something else.

    Try this:
     
    double scale = 72/...;  //be reasonable, 600 won't work, 72 pixels-per-inch may be just fine 
    
    Graphics2D g2d = (Graphics2D) printerGraphics; 
    
    g2d.scale(scale,scale);
    g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                         RenderingHints.VALUE_INTERPOLATION_BICUBIC);
    g2d.drawImage(image,xMargin,yMargin,
            (int) Math.floor(pageFormat.getWidth()/scale),
            (int) Math.floor(pageFormat.getHeight()/scale),null); 
    This should (in theory) scale the image to the page's size using bicubic interpolation, and print it at what ever pixels-per-inch you specify. The crappy output you were getting could of been the nearest neighbor interpolation, the 72 ppi, or some combination of both.
  • 2. Re: printing an image to a printer result in poor quality
    913191 Newbie
    Currently Being Moderated
    Great, that did the trick.

    Thanks

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points