Link to home
Start Free TrialLog in
Avatar of modsiw
modsiw

asked on

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.
Avatar of appxpete
appxpete

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.


Avatar of modsiw

ASKER

How do I do this with a java.awt.graphic?
Avatar of CEHJ
jcomponent.setDoubleBuffered(false);
Avatar of modsiw

ASKER

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); }
      }
    }

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);
}
}
}

}
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
Avatar of modsiw

ASKER

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.
Avatar of modsiw

ASKER

appxpete - anychance you have that in english?
however there was nothing wrong in my first comment, both predicates are correct :)
Avatar of modsiw

ASKER

How do you use java.awt.PageAttributes.setPrinterResolution with java.awt.print?
>>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
Avatar of modsiw

ASKER

Hoomanv - didn't work
SOLUTION
Avatar of appxpete
appxpete

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of modsiw

ASKER

Hoomanv - didn't work err this should be appxpete - didn't work.


Thanks for addition stuff appxpete. Looking at it now
Avatar of modsiw

ASKER

Thanks also Hoomanv, looking at it now.
Avatar of modsiw

ASKER

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. =(
Avatar of modsiw

ASKER

>>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.
Avatar of modsiw

ASKER

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); }
      }

    }
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of modsiw

ASKER

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.

Avatar of modsiw

ASKER

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.
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);
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));
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Or you can call the scale method :

... print(Graphics g,...)
{
    Graphics2D g2d=(Graphics2D)g;
    g2d.scale(72,600); // 600 dpi
...
}
   g2d.scale(72.0/600,72.0/600); // 600 dpi
Avatar of modsiw

ASKER

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.
:-)
Avatar of modsiw

ASKER

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.
Avatar of modsiw

ASKER

I'd liek to request that the grade be changed to an A.
Avatar of modsiw

ASKER

Thanks much
Thanks :-)