2

i am stuck currently when printing a jpeg file with the default printer. In my program when i select an image from a folder, i need to print it using the printer default settings (paper size, margins, orientation).

Currently i got this:

PrintService printService = PrintServiceLookup.lookupDefaultPrintService();
final BufferedImage image = ImageIO.read(new File("car.jpg"));

PrinterJob printJob = PrinterJob.getPrinterJob();
printJob.setPrintService(printService);
printJob.setPrintable(new Printable(){
  @Override
  public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException{
      if (pageIndex == 0) {
          graphics.drawImage(image, 0, 0, (int)pageFormat.getWidth(), (int)pageFormat.getHeight(), null);
          return PAGE_EXISTS;
      else return NO_SUCH_PAGE;
  }
}

printJob.print();

The default settings for my printer right now for size is: 10 x 15 cm (4 x 6 in) but when i set my program to print the given image, it displays only a small section of the paper.

Please help me out.

EDIT

thanks everyone for their help, i managed to find the answer posted by another user at Borderless printing

Community
  • 1
  • 1
anonimoo90
  • 355
  • 3
  • 13

2 Answers2

4

Make sure that you are, first, translating the Graphics context to fit within inthe imagable area...

g2d.translate((int) pageFormat.getImageableX(),
              (int) pageFormat.getImageableY());

Next, make sure you are using the imageableWidth and imageableHeight of the PageFormat

double width = pageFormat.getImageableWidth();
double height = pageFormat.getImageableHeight();

and not the width/height properties. Many of these things get translated from different contexts...

graphics.drawImage(image, 0, 0, (int)width, (int)height, null);

The getImageableWidth/Height returns the page size within the context of the page orientation

Printing pretty much assumes a dpi of 72 (don't stress, the printing API can handle much higher resolutions, but the core API assumes 72dpi)

This means that a page of 10x15cm should translate to 283.46456664x425.19684996 pixels. You can verify this information by using a System.out.println and dumping the results of getImageableWidth/Height to the console.

If you're getting different settings, it's possible that Java has overridden the default page properties

For example...

You have two choices...

You could...

Show the PrintDialog and ensure that the correct page settings are selected

PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
aset.add(new PrinterResolution(300, 300, PrinterResolution.DPI));
aset.add(new MediaPrintableArea(0, 0, 150, 100, MediaPrintableArea.MM));

PrinterJob pj = PrinterJob.getPrinterJob();
pj.setPrintable(new PrintTask()); // You Printable here

if (pj.printDialog(aset)) {
    try {
        pj.print(aset);
    } catch (PrinterException ex) {
        ex.printStackTrace();
    }
}

Or you could...

Just manually set the paper/page values manually...

public static void main(String[] args) {
    PrinterJob pj = PrinterJob.getPrinterJob();
    PageFormat pf = pj.defaultPage();
    Paper paper = pf.getPaper();
    // 10x15mm
    double width = cmsToPixel(10, 72);
    double height = cmsToPixel(15, 72);
    paper.setSize(width, height);
    // 10 mm border...
    paper.setImageableArea(
                    cmsToPixel(0.1, 72),
                    cmsToPixel(0.1, 72),
                    width - cmsToPixel(0.1, 72),
                    height - cmsToPixel(0.1, 72));
    // Orientation
    pf.setOrientation(PageFormat.PORTRAIT);
    pf.setPaper(paper);
    PageFormat validatePage = pj.validatePage(pf);
    pj.setPrintable(new Printable() {
        @Override
        public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException {
            // Your code here
            return NO_SUCH_PAGE;
        }

    },  validatePage);
    try {
        pj.print();
    } catch (PrinterException ex) {
        ex.printStackTrace();
    }
}

// The number of CMs per Inch
public static final double CM_PER_INCH = 0.393700787d;
// The number of Inches per CMs
public static final double INCH_PER_CM = 2.545d;
// The number of Inches per mm's
public static final double INCH_PER_MM = 25.45d;

/**
 * Converts the given pixels to cm's based on the supplied DPI
 *
 * @param pixels
 * @param dpi
 * @return
 */
public static double pixelsToCms(double pixels, double dpi) {
    return inchesToCms(pixels / dpi);
}

/**
 * Converts the given cm's to pixels based on the supplied DPI
 *
 * @param cms
 * @param dpi
 * @return
 */
public static double cmsToPixel(double cms, double dpi) {
    return cmToInches(cms) * dpi;
}

/**
 * Converts the given cm's to inches
 *
 * @param cms
 * @return
 */
public static double cmToInches(double cms) {
    return cms * CM_PER_INCH;
}

/**
 * Converts the given inches to cm's
 *
 * @param inch
 * @return
 */
public static double inchesToCms(double inch) {
    return inch * INCH_PER_CM;
}
Community
  • 1
  • 1
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • hi, i tried what u said and it printed the image the same way, it just shrank the image to half the paper size (10x15cm), i displayed the result of getImageableWidth/height and it gave 0.5 – anonimoo90 Nov 19 '14 at 23:57
  • Then it is likely that Java is changing the `PageFormat` – MadProgrammer Nov 19 '14 at 23:59
  • what should i do then? i need the program to be able to fit image to the paper size defined on the printer. – anonimoo90 Nov 20 '14 at 00:01
  • Thanks for the help, i tried the first method using the PrintRequestAttributeSet but it didnt work, it printed a small image on the paper and about the second method, i cant use that one because as i said, the program should be able to fit the image given to the paper size defined on the printer by the user. – anonimoo90 Nov 20 '14 at 00:24
  • Then the first method should work, as you are specifying the values the the printer should use... – MadProgrammer Nov 20 '14 at 00:25
  • I have been confronted with the same problem and your first solution helped me out! Unfortunately I now have big gaps on the sides of the image (about 2.5 cm on each side and 2 cm at the bottom.) I have tried to play around adding values to `width, height, pageFormat.getImageableX/Y` but that would just move the image beneath the white space. Is this a fixed space that will always be there or is there a way to smaller it? – geisterfurz007 Oct 10 '16 at 06:58
  • @geisterfurz007 From memory the scaling works on a scale to fit algorithm, you might consider using a fill instead, you may also need to adjust the printable area (MediaPrintableArea), but at some point the printer will reject your settings and use its own – MadProgrammer Oct 10 '16 at 07:05
  • How would this `fill` (-command) look like? I am new to Java and eager to learn! – geisterfurz007 Oct 10 '16 at 08:00
  • @geisterfurz007 Maybe something like [this](http://stackoverflow.com/questions/11959758/java-maintaining-aspect-ratio-of-jpanel-background-image/11959928#11959928) – MadProgrammer Oct 10 '16 at 08:24
  • @MadProgrammer Thanks for the idea! I like the concept. However I found something else [here](http://stackoverflow.com/a/10484729/6707985) that helped out. Maybe someone will find it from here :) – geisterfurz007 Oct 10 '16 at 12:59
0

It looks like you are printing the image with dimensions based on the PageFormat, rather than the actual image's dimensions, your drawImage() method should look something like this

graphics.drawImage(image, 0, 0, image.getWidth(), image.getHeight(), null)
Ben Marshall
  • 171
  • 2
  • 12
  • i tried that and the result was the same :(, the image only cover half the size of the paper...i need the image to fit the paper size. image is 1200x800 and paper is (10x15cm) – anonimoo90 Nov 19 '14 at 23:46
  • Ah ok, my solution would print the image at its full size, if you want to scale it down it looks like the above answer should work, either that or you'd have to decide on some scale factor to divide the height and width by – Ben Marshall Nov 19 '14 at 23:50