Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 2664
  • Last Modified:

Printing a BufferedImage at a high resolution.

Is there a way to print an image at a resolution greater than 72DPI?

If so, how do you change the resolution?

I'm using java.awt.print.
0
modsiw
Asked:
modsiw
  • 17
  • 5
  • 4
  • +2
4 Solutions
 
appxpeteCommented:
Found this is a Sun forum:
------------------------------
you have to disable double-buffering of your printable component. otherwise, the off-screen image used for double-buffering, with 72 dpi, is rendered on the the printers graphics context.

with double-buffering disabled, the component will be rendered on the printers graphics context without thinking about screen-resolution.


0
 
modsiwAuthor Commented:
How do I do this with a java.awt.graphic?
0
 
CEHJCommented:
jcomponent.setDoubleBuffered(false);
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
modsiwAuthor Commented:
Sadly, I am not using swing. I'm using java.awt.print

    if (aryPrintDoc.length > 0) {
      Book printBook = new Book();
      printJob = PrinterJob.getPrinterJob();
      for (int i = 0; i < aryPrintDoc.length; i++)
        for (int j = 0; j < aryPrintDoc[i].countPage(); j++)
          printBook.append(aryPrintDoc[i].getPrintableAt(j),aryPrintDoc[i].getPageFormat());
      printJob.setPageable(printBook);
      if (printJob.printDialog()) {
        try { printJob.print(); }
        catch (Exception exception) { System.out.println("Printing Error: " + exception); }
      }
    }

0
 
appxpeteCommented:
Also found this out on the Sun forums.  It has a section that sets the print resolution.  Does this help you any?

try this:

// ImprimeDetalleAction.java
//
package ayto;

import javax.print.attribute.*;
import javax.print.attribute.standard.*;

import java.awt.*;

import java.awt.event.*;
import java.awt.print.*;
import javax.swing.*;

import aytobeans.*;

public class ImprimeDetalleAction
extends AytoAction {

public void actionPerformed(ActionEvent ev) {

Thread detThread = new Thread() {
public void run() {
doPrint();
}
};
detThread.start();

}

public void doPrint() {
JDesktopPane desk;
InterfaceEntornoDetalleAyto reg;
PrinterJob pj = PrinterJob.getPrinterJob();
PrintRequestAttributeSet attributes;
//Resoluciones 300,400,600
PrinterResolution ps = new PrinterResolution(400, 400,
PrinterResolution.DPI);

desk = conAyto.getDesk();
reg = (InterfaceEntornoDetalleAyto) desk.getSelectedFrame();

ComponenteParaImprimir cp = new ComponenteParaImprimir( (JPanel) reg.
getEntornoDetalle().getPanelDetalle(),ComponenteParaImprimir.HARDCOPY);

PageFormat pf = pj.defaultPage();
attributes = new HashPrintRequestAttributeSet();
//pf = pj.pageDialog(attributes);
//pf = pj.pageDialog(pf);

attributes.add(ps);

Paper papel = new Paper();
double margen = 20;
papel.setSize(900, 1260);
papel.setImageableArea(margen, margen,
papel.getWidth() - margen * 2,
papel.getHeight() - margen * 2);
pf.setPaper(papel);

pj.setPrintable(cp, pf);
if (pj.printDialog()) {
try {
pj.print(attributes);
}
catch (PrinterException pe) {
System.out.println(pe);
}
}
}

}
0
 
hoomanvCommented:
I think java.awt.PageAttributes.setPrinterResosution() is the way to go
seems wasitng time trying to print an image with any greater dpi than it is already in
0
 
modsiwAuthor Commented:
hoomanv - I don't think you understand the question. I have a high resolution image. I need to print it at a finer DPI than 72.

appxpete - Thank you, I'm looking over it now.
0
 
modsiwAuthor Commented:
appxpete - anychance you have that in english?
0
 
hoomanvCommented:
however there was nothing wrong in my first comment, both predicates are correct :)
0
 
modsiwAuthor Commented:
How do you use java.awt.PageAttributes.setPrinterResolution with java.awt.print?
0
 
CEHJCommented:
>>I need to print it at a finer DPI than 72.

If your objective is to make it smaller then it may be better to scale it, as the printer could ignore a request to print at a finer resolution
0
 
modsiwAuthor Commented:
Hoomanv - didn't work
0
 
appxpeteCommented:
From looking over the classes and the examples I found it looks like this is what might work.

1. You create a PrinterJob with PrinterJob.getPrinterJob()

2. When calling print, you can pass a PrintRequestAttributeSet (or rather a concrete implementation
like HashPrintRequestAttributeSet).

3. You can add Attribute instances to the attribute set.

4. There is an Attribute instance called javax.print.attribute.standard.PrinterResolution.

So create an instance of PrinterResolution with the desired resolution, then set it in a
PrintRequestAttributeSet, then pass that to the print method in PrinterJob.

Maybe like this?

    if (aryPrintDoc.length > 0) {
      Book printBook = new Book();
      printJob = PrinterJob.getPrinterJob();
      PrintRequestAttributeSet attributes;
      attributes = new HashPrintRequestAttributeSet();
      PrinterResolution ps = new PrinterResolution(400, 400,PrinterResolution.DPI);
      attributes.add(ps);
      for (int i = 0; i < aryPrintDoc.length; i++)
        for (int j = 0; j < aryPrintDoc[i].countPage(); j++)
          printBook.append(aryPrintDoc[i].getPrintableAt(j),aryPrintDoc[i].getPageFormat());
      printJob.setPageable(printBook);
      if (printJob.printDialog()) {
        try { printJob.print(attributes); }
        catch (Exception exception) { System.out.println("Printing Error: " + exception); }
      }
    }
0
 
hoomanvCommented:
> How do you use java.awt.PageAttributes.setPrinterResolution with java.awt.print?
for example

import java.awt.*;
import java.awt.print.*;

public class PrintFontIsRaster
{
    public static void main(String[] args)
    {
        try
        {
            Frame frame = new Frame();
                       
            JobAttributes jobAttr = new JobAttributes();
            PageAttributes pageAttr = new PageAttributes();
            pageAttr.setPrinterResolution( 600 );
            pageAttr.setPrintQuality( 5 );
            pageAttr.setOrigin( PageAttributes.OriginType.PHYSICAL );

            printSomething( frame, jobAttr, pageAttr, PageAttributes.OrientationRequestedType.PORTRAIT );

            frame.dispose();
            System.gc();
        }
        catch( Exception e )
        {
        }
        System.exit(0);
    }
            
    public static void printSomething( Frame frame, JobAttributes jobAttr,
PageAttributes pageAttr, PageAttributes.OrientationRequestedType orientation )
    {
        pageAttr.setOrientationRequested( orientation );

        PrintJob printJob = Toolkit.getDefaultToolkit().getPrintJob(frame, "JDK1.3", jobAttr, pageAttr );
        if ( printJob != null )
        {
            Graphics g = printJob.getGraphics();

            int res = pageAttr.getPrinterResolution()[0];
                              
            g.setFont( new Font("Monospaced", Font.PLAIN, adjust(80,res)) );
            g.setColor( Color.black );
            g.drawString( "TEXT IS BITMAP", adjust(75,res), adjust(300,res) );
                              
            g.dispose();

            printJob.end();
        }
    }
          
    public static int adjust( int pixel, int res )
    {
        int screenRes = Toolkit.getDefaultToolkit().getScreenResolution();
        return (int)((pixel * res) / screenRes);
    }
}

> Hoomanv - didn't work
OK, i'll look for a working way
0
 
modsiwAuthor Commented:
Hoomanv - didn't work err this should be appxpete - didn't work.


Thanks for addition stuff appxpete. Looking at it now
0
 
modsiwAuthor Commented:
Thanks also Hoomanv, looking at it now.
0
 
modsiwAuthor Commented:
PrintJob printJob = Toolkit.getDefaultToolkit().getPrintJob(frame, "JDK1.3", jobAttr, pageAttr );

The above is java.awt.PrintJob. What I need this to work with is a java.awt.print.PrinterJob. =(
0
 
modsiwAuthor Commented:
>>If your objective is to make it smaller then it may be better to scale it, as the printer could ignore a request to print at a finer resolution

I have an image (about 900wide by 300high) that I need to print on a page (in portrait) with out loosing detail. The image contains small text.
0
 
modsiwAuthor Commented:
This seems to have no affect on the print.

    if (aryPrintDoc.length > 0) {

      PrinterResolution ps = new PrinterResolution(600,600,PrinterResolution.DPI);
      HashPrintRequestAttributeSet att = new HashPrintRequestAttributeSet();
      att.add(ps);

      Book printBook = new Book();
      printJob = PrinterJob.getPrinterJob();
      for (int i = 0; i < aryPrintDoc.length; i++)
        for (int j = 0; j < aryPrintDoc[i].countPage(); j++)
          printBook.append(aryPrintDoc[i].getPrintableAt(j),aryPrintDoc[i].getPageFormat());
      printJob.setPageable(printBook);
      if (printJob.printDialog()) {
        //try { printJob.print(); }
        try { printJob.print(att); }
        catch (Exception exception) { System.out.println("Printing Error: " + exception); }
      }

    }
0
 
CEHJCommented:
>>that I need to print on a page (in portrait) with out loosing detail. The image contains small text.

Altering the resolution of your target device, even if it's possible, will have no appreciable effect on deterioration of the text due to resizing. Here's why:

http://www.rideau-info.com/photos/mythdpi.html
0
 
modsiwAuthor Commented:
CEHJ:

I read, and I beleive I understand your link. I don't think we are communicating the problem clearly. I do not wish to print a low res image at high res. I want to print a high res image at high res. If I can not, I am forced to resize the image to a lower res so that it can print at low res (pixil for pixil) with out going off the page.

The orginal image is approx 900 pixil's wide. Inorder for it to print on the page at 72 DPI it must be resized, which causes distortion. I would like to increase the printing DPI so that it will fit on the page with out resizing and thus distorting.

image = image.getScaledInstance(550,-1,java.awt.Image.SCALE_SMOOTH); Causes the image to get blurry.

0
 
modsiwAuthor Commented:
Perhaps I should rephrase the question:

Using the java.awt.print interface; How can I print an image sized 860 x 272 with out it going off the edge of the paper or being distorted by resizing.
0
 
CEHJCommented:
You will probably get a blurred outcome like that. Try something like

    BufferedImage thumbImage = new BufferedImage(thumbWidth,
      thumbHeight, BufferedImage.TYPE_INT_RGB);
    Graphics2D graphics2D = thumbImage.createGraphics();
    graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
      RenderingHints.VALUE_INTERPOLATION_BILINEAR);
0
 
hoomanvCommented:
I've tested it and discovered that the outcome of getScaledInstance is still a bit smoother than CEHJ's suggestion

// attempt 1

   BufferedImage src = ImageIO.read(new File(srcFile));
   BufferedImage dest = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
   Graphics2D g = dest.createGraphics();
   Image scaled = src.getScaledInstance(width, height, java.awt.Image.SCALE_SMOOTH);
   g.drawImage(scaled, 0, 0, null);
   ImageIO.write(dest, "JPG", new File(destFile));

// attempt 2

   BufferedImage src = ImageIO.read(new File(srcFile));
   BufferedImage dest = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
   Graphics2D g = dest.createGraphics();
   g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
   AffineTransform at = AffineTransform.getScaleInstance((double)width / src.getWidth(),
                                                                                    (double)height / src.getHeight());
   g.drawRenderedImage(src, at);
   ImageIO.write(dest, "JPG", new File(destFile));
0
 
WebstormCommented:
Hi modsiw,

Graphics use 1/72 dot per inch, and coordinates are double, try calling drawImage(Image,x,y,w,h,Observer) to scale it on the print Graphics :

int res_w=600,  // 600 dpi
     res_h=600;  // 600 dpi
double w=image.getWidth(),h=image.getHeight();
printgraphics.drawImage(image,x,y, w*72/res_w,h*72/res_h, null);
0
 
WebstormCommented:
Or you can call the scale method :

... print(Graphics g,...)
{
    Graphics2D g2d=(Graphics2D)g;
    g2d.scale(72,600); // 600 dpi
...
}
0
 
WebstormCommented:
   g2d.scale(72.0/600,72.0/600); // 600 dpi
0
 
modsiwAuthor Commented:
This method:

drawImage(Image img, int x, int y, int width, int height, ImageObserver observer) of java.awt.Graphics

did the trick with out causing distortion.
0
 
CEHJCommented:
:-)
0
 
modsiwAuthor Commented:
It provided a solution but did not answer the orginal question was my reasoning at the time.

Given the work and insight involved, an A would have been a more appropirate grade.

Many apologies for any trouble this may have caused. The help was greatly appreciated.
0
 
modsiwAuthor Commented:
I'd liek to request that the grade be changed to an A.
0
 
modsiwAuthor Commented:
Thanks much
0
 
WebstormCommented:
Thanks :-)
0

Featured Post

Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

  • 17
  • 5
  • 4
  • +2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now