java setting resolution and print size for an Image

时光总嘲笑我的痴心妄想 提交于 2019-12-14 04:16:33

问题


I wrote a program that generates a BufferedImage to be displayed on the screen and then printed. Part of the image includes grid lines that are 1 pixel wide. That is, the line is 1 pixel, with about 10 pixels between lines. Because of screen resolution, the image is displayed much bigger than that, with several pixels for each line. I'd like to draw it smaller, but when I scale the image (either by using Image.getScaledInstance or Graphics2D.scale), I lose significant amounts of detail.

I'd like to print the image as well, and am dealing with the same problem. In that case, I am using this code to set the resolution:

HashPrintRequestAttributeSet set = new HashPrintRequestAttributeSet();
PrinterResolution pr = new PrinterResolution(250, 250, ResolutionSyntax.DPI);
set.add(pr);
job.print(set);

which works to make the image smaller without losing detail. But the problem is that the image is cut off at the same boundary as if I hadn't set the resolution. I'm also confused because I expected a larger number of DPI to make a smaller image, but it's working the other way.

I'm using java 1.6 on Windows 7 with eclipse.


回答1:


Regarding the image being cut-off on the page boundary, have you checked the clip region of the graphics? I mean try :

System.out.println(graphics.getClipBounds());

and make sure it is correctly set.




回答2:


It sounds like your problem is that you are making the grid lines part of the BufferedImage and it doesn't look good when scaled. Why not use drawLine() to produce the grid after your image has been drawn?




回答3:


Code for Convert image with dimensions using Java and print the converted image.

Class: ConvertImageWithDimensionsAndPrint.java

package com.test.convert;

import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;

import javax.imageio.ImageIO;

public class ConvertImageWithDimensionsAndPrint {
    private static final int IMAGE_WIDTH = 800;
    private static final int IMAGE_HEIGHT = 1000;

public static void main(String[] args) {
    try {
        String sourceDir = "C:/Images/04-Request-Headers_1.png";
        File sourceFile = new File(sourceDir);
        String destinationDir = "C:/Images/ConvertedImages/";//Converted images save here
        File destinationFile = new File(destinationDir);
        if (!destinationFile.exists()) {
            destinationFile.mkdir();
        }
        if (sourceFile.exists()) {
            String fileName = sourceFile.getName().replace(".png", "");
            BufferedImage bufferedImage = ImageIO.read(sourceFile);
            int type = bufferedImage.getType() == 0 ? BufferedImage.TYPE_INT_ARGB : bufferedImage.getType();

            BufferedImage resizedImage = new BufferedImage(IMAGE_WIDTH, IMAGE_HEIGHT, type);
            Graphics2D graphics2d = resizedImage.createGraphics();
            graphics2d.drawImage(bufferedImage, 0, 0, IMAGE_WIDTH, IMAGE_HEIGHT, null);//resize goes here
            graphics2d.dispose();

            ImageIO.write(resizedImage, "png", new File( destinationDir + fileName +".png" ));

            int oldImageWidth = bufferedImage.getWidth();
            int oldImageHeight = bufferedImage.getHeight();
            System.out.println(sourceFile.getName() +" OldFile with Dimensions: "+ oldImageWidth +"x"+ oldImageHeight);
            System.out.println(sourceFile.getName() +" ConvertedFile converted with Dimensions: "+ IMAGE_WIDTH +"x"+ IMAGE_HEIGHT);

            //Print the image file
            PrintActionListener printActionListener = new PrintActionListener(resizedImage);
            printActionListener.run();
        } else {
            System.err.println(destinationFile.getName() +" File not exists");
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}
}

Reference of PrintActionListener.java

package com.test.convert;

import java.awt.Graphics;
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;

public class PrintActionListener implements Runnable {

private BufferedImage image;

public PrintActionListener(BufferedImage image) {
    this.image = image;
}

@Override
public void run() {
    PrinterJob printJob = PrinterJob.getPrinterJob();
    printJob.setPrintable(new ImagePrintable(printJob, image));

    if (printJob.printDialog()) {
        try {
            printJob.print();
        } catch (PrinterException prt) {
            prt.printStackTrace();
        }
    }
}

public class ImagePrintable implements Printable {

    private double x, y, width;

    private int orientation;

    private BufferedImage image;

    public ImagePrintable(PrinterJob printJob, BufferedImage image) {
        PageFormat pageFormat = printJob.defaultPage();
        this.x = pageFormat.getImageableX();
        this.y = pageFormat.getImageableY();
        this.width = pageFormat.getImageableWidth();
        this.orientation = pageFormat.getOrientation();
        this.image = image;
    }

    @Override
    public int print(Graphics g, PageFormat pageFormat, int pageIndex) throws PrinterException {
        if (pageIndex == 0) {
            int pWidth = 0;
            int pHeight = 0;
            if (orientation == PageFormat.PORTRAIT) {
                pWidth = (int) Math.min(width, (double) image.getWidth());
                pHeight = pWidth * image.getHeight() / image.getWidth();
            } else {
                pHeight = (int) Math.min(width, (double) image.getHeight());
                pWidth = pHeight * image.getWidth() / image.getHeight();
            }
            g.drawImage(image, (int) x, (int) y, pWidth, pHeight, null);
            return PAGE_EXISTS;
        } else {
            return NO_SUCH_PAGE;
        }
    }

}

}

Output:

04-Request-Headers_1.png OldFile with Dimensions: 1224x1584
04-Request-Headers_1.png ConvertedFile converted with Dimensions: 800x1000

After conversion of a image a Print window will be open for printing the converted image. The window displays like below, Select the printer from Name dropdown and Click OK button.




回答4:


I had the same problem. Here is my solution.

First change the resolution of the print job...

    PrinterJob job = PrinterJob.getPrinterJob();
    // Create the paper size of our preference
    double cmPx300 = 300.0 / 2.54;
    Paper paper = new Paper();
    paper.setSize(21.3 * cmPx300, 29.7 * cmPx300);
    paper.setImageableArea(0, 0, 21.3 * cmPx300, 29.7 * cmPx300);
    PageFormat format = new PageFormat();
    format.setPaper(paper);
    // Assign a new print renderer and the paper size of our choice !
    job.setPrintable(new PrintReport(), format);

    if (job.printDialog()) {
        try {
            HashPrintRequestAttributeSet set = new HashPrintRequestAttributeSet();
            PrinterResolution pr = new PrinterResolution((int) (dpi), (int) (dpi), ResolutionSyntax.DPI);
            set.add(pr);
            job.setJobName("Jobname");
            job.print(set);
        } catch (PrinterException e) {
        }
    }

Now you can draw everything you like into the new high resolution paper like this !

    public class PrintReport implements Printable {

    @Override
    public int print(Graphics g, PageFormat pf, int page) throws PrinterException {
        // Convert pixels to cm to lay yor page easy on the paper...
        double cmPx = dpi / 2.54;
        Graphics2D g2 = (Graphics2D) g;
        int totalPages = 2; // calculate the total pages you have...
        if (page < totalPages) {

            // Draw Page Header
            try {
                BufferedImage image = ImageIO.read(ClassLoader.getSystemResource(imgFolder + "largeImage.png"));
                g2.drawImage(image.getScaledInstance((int) (4.8 * cmPx), -1, BufferedImage.SCALE_SMOOTH), (int) (cmPx),
                        (int) (cmPx), null);
            } catch (IOException e) {
            }
            // Draw your page as you like...
            // End of Page
            return PAGE_EXISTS;
        } else {
            return NO_SUCH_PAGE;
        }
    }



回答5:


You can use either of the following to improve the quality of the scaling. I believe BiCubic gives better results but is slower than BILINEAR.

g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);

I would also not use Image.getScaledInstance() as it is very slow. I'm not sure about the printing as I'm struggling with similar issues.



来源:https://stackoverflow.com/questions/3057514/java-setting-resolution-and-print-size-for-an-image

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!