Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to design an image in java to be printed on a 300 dpi printer

Tags:

java

I want to make an image in Java and print it on a 300dpi label printer on a label, sized 150 x 100 mm. How can I make the image so that a line (or whatever kind of element) is printed exactly at position (10,10) (in millimeters), and that line is ended at position (10,50)?

In other words: My challenge is not how to make a line (I'm using Graphics2D, bufferedImage), but it is how to be able to tell exactly where this line has to be (in millimeters) on the label.

Any Ideas?

like image 950
Jakob Mathiasen Avatar asked Sep 24 '13 07:09

Jakob Mathiasen


People also ask

Can you print 300 DPI image?

Recommended minimum resolution for printing is 300 dpi; computer monitors generally have a display setting of 72 dpi or 96 dpi. If we indicate that some of your images have low resolution, they may not look bad on your monitor but will likely print blurry or jagged.

How do I make an image 300 ppi?

Click Image > Image Size. Check the “Resample” box. Set the resolution to 300 PPI and click “OK”

How do I make an image a DPI?

To change an image's DPI in Photoshop, go to Image > Image Size. Uncheck Resample Image, because this setting will upscale your image, which will make it lower quality. Now, next to Resolution, type in your preferred resolution, set as Pixels/Inch. Notice how the Width and Height figures change, too.


1 Answers

Java's print API basically works on the assumption that everything is done at 72 dpi. This means that you can use this as bases for converting to/from different measurements...

This just means you need and start value and target measurement...

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

So, in order to print the image at 10mmx10mm, you would need to convert this to pixel's per inch

double point = cmsToPixel(1, 72);

You're probably also going to need to think about maybe downsizing the image to fit into the printable area.

For some examples...

  • Fit image into the printing area
  • fitting PrinterJob Object to specific print format of BufferedImage

Update with test results

So I did some tests (code to follow)...

First, I set up a PrintRequestAttributeSet to request only print services capable of supporting 300x300 dpi...

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

When printed, my Printable was passed an imageable area of 425.20 x 283.46 pixels, which equates to 15.03 x 10.02 cm @ 72dpi (roughly). This is how Java works, it's basic print API has always worked on the assumption of 72dpi.

So. If I prepare an image of 10 x 50 mm @ 72 DPI, I get an image size of 28.346 x 141.732 pixels, which will easily fit within the imageable area (of 425.20 x 283.46).

However, if I use 300 dpi, I get a image size of 118.11 x 590.551 pixels, which is going to run us into trouble, requiring us to downscale the image...

This, actually, may be desirable, you will have to perform some testing to find out.

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
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 javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.MediaPrintableArea;
import javax.print.attribute.standard.PrinterResolution;

public class TestHiResPrinting {

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                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());

                if (pj.printDialog(aset)) {
                    try {
                        pj.print(aset);
                    } 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;
    }

    public static class PrintTask implements Printable {

        private BufferedImage img;

        public PrintTask() {
            double width = cmsToPixel(1, 72);
            double height = cmsToPixel(5, 72);

            img = new BufferedImage((int) Math.round(width), (int) Math.round(height), BufferedImage.TYPE_INT_ARGB);
            Graphics2D g2d = img.createGraphics();
            g2d.setColor(Color.RED);
            g2d.draw(new Rectangle2D.Double(0, 0, width - 1, height - 1));
            g2d.draw(new Line2D.Double(0, 0, width, height));
            g2d.draw(new Line2D.Double(0, height, width, 0));
            g2d.dispose();
        }

        @Override
        public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException {
            int result = NO_SUCH_PAGE;
            if (pageIndex < 2) {
                Graphics2D g2d = (Graphics2D) graphics;
                double width = pageFormat.getImageableWidth();
                double height = pageFormat.getImageableHeight();

                System.out.println("Page width = " + width + " = " + pixelsToCms(width, 72));
                System.out.println("Page height = " + height + " = " + pixelsToCms(height, 72));

                g2d.translate((int) pageFormat.getImageableX(),
                                (int) pageFormat.getImageableY());
                double x = cmsToPixel(1, 72);
                double y = cmsToPixel(1, 72);
                System.out.println("Draw At " + x + "x" + y);
                g2d.drawRect(0, 0, (int)width - 1, (int)height - 1);
                g2d.drawImage(img, (int)x, (int)y, null);
                result = PAGE_EXISTS;
            }
            return result;
        }

    }
}
like image 198
MadProgrammer Avatar answered Oct 24 '22 21:10

MadProgrammer