java设置图像的分辨率和打印大小
我编写了一个程序,生成一个BuffereImage,显示在屏幕上,然后打印出来。图像的一部分包括1像素宽的网格线。也就是说,线是1个像素,线之间大约有10个像素。由于屏幕分辨率的原因,图像显示的尺寸要大得多,每行有几个像素。我想把它画得更小,但是当我缩放图像时(通过使用image.getscaleInstance或Graphics2D.scale),我会丢失大量的细节 我也想打印图像,我正在处理同样的问题。在这种情况下,我使用以下代码设置分辨率:java设置图像的分辨率和打印大小,java,image,printing,resolution,Java,Image,Printing,Resolution,我编写了一个程序,生成一个BuffereImage,显示在屏幕上,然后打印出来。图像的一部分包括1像素宽的网格线。也就是说,线是1个像素,线之间大约有10个像素。由于屏幕分辨率的原因,图像显示的尺寸要大得多,每行有几个像素。我想把它画得更小,但是当我缩放图像时(通过使用image.getscaleInstance或Graphics2D.scale),我会丢失大量的细节 我也想打印图像,我正在处理同样的问题。在这种情况下,我使用以下代码设置分辨率: HashPrintRequestAttribut
HashPrintRequestAttributeSet set = new HashPrintRequestAttributeSet();
PrinterResolution pr = new PrinterResolution(250, 250, ResolutionSyntax.DPI);
set.add(pr);
job.print(set);
这样可以在不丢失细节的情况下使图像变小。但问题是,图像在同一边界处被截断,就好像我没有设置分辨率一样。我也很困惑,因为我希望更多的DPI可以产生更小的图像,但事实恰恰相反
我在Windows7和eclipse上使用Java1.6。听起来您的问题是,您将网格线作为BuffereImage的一部分,缩放时看起来不太好。为什么不在绘制图像后使用drawLine()生成网格?您可以使用以下任一方法来提高缩放质量。我相信双三次曲线给出了更好的结果,但比双线性曲线慢
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
我也不会使用Image.getScaleInstance(),因为它非常慢。我不确定打印是否正确,因为我正在努力解决类似的问题 关于在页面边界上截取的图像,是否检查了图形的剪辑区域?我的意思是尝试:
System.out.println(graphics.getClipBounds());
并确保其设置正确。使用Java编码转换带尺寸的图像,并打印转换后的图像 类:convertImagewithdimensions和print.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();
}
}
}
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;
}
}
}
}
输出:
04-Request-Headers_1.png OldFile with Dimensions: 1224x1584
04-Request-Headers_1.png ConvertedFile converted with Dimensions: 800x1000
图像转换后,打印窗口将打开,以打印转换后的图像。窗口显示如下,从“名称”下拉列表中选择打印机,然后单击“确定”按钮
我也有同样的问题。这是我的解决办法 首先更改打印作业的分辨率
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) {
}
}
现在你可以像这样把所有你喜欢的东西都画进新的高分辨率纸里
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;
}
}
公共类PrintReport实现可打印{
@凌驾
公共整型打印(图形g、页面格式pf、整型页面)引发PrinterException{
//将像素转换为厘米,以便轻松地将页面放在纸上。。。
双cmPx=dpi/2.54;
图形2d g2=(图形2d)g;
int totalPages=2;//计算您拥有的总页面数。。。
如果(第页<总页数){
//绘图页眉
试一试{
BuffereImage=ImageIO.read(ClassLoader.getSystemResource(imgFolder+“largeImage.png”);
g2.drawImage(image.getScaledInstance((int)(4.8*cmPx),-1,buffereImage.SCALE_平滑),(int)(cmPx),
(int)(cmPx),空;
}捕获(IOE异常){
}
//画你喜欢的页面。。。
//页尾
返回页面_存在;
}否则{
不返回此类页面;
}
}
我不确定你的建议。也许我应该缩放图像,然后画线?我不想缩放图像或线,我的屏幕和打印机都有足够的DPI来显示所有细节。我提到了线,但也有很多小的(10像素正方形)如果按1/2的比例缩放,图标会变得模糊。这对我来说没有意义,因为这不容易(可能很容易,我只是不知道怎么做)。Printable提供了一个Graphics2D对象:public int print(Graphics g,PageFormat pf,int page)
。不要将页面渲染为巨大的像素化图像,而是将其渲染为矢量图形调用:例如,多个g.drawLine()
和g.drawImage())
调用。我会试试看它的外观。如果我理解正确,这只会使不太详细的显示看起来更好。没有办法显示和打印所有细节吗?你只能打印图像中的细节。这会给线条元素添加无限的细节。如果单个图标有We re detail by the resolution of the giant BuffereImage这也会解决这个问题。谢谢你的耐心!我对屏幕显示的看法是错误的。你说得对,它只是显示了我要求它显示的内容,没有办法在不丢失细节的情况下使它变小。但我仍然无法打印我想要的细节。我把所有细节都放在这是我想要的原始图像。打印时,它会打印出巨大的图像,每个像素使用多个点。我可以使用PrinterResolution使其绘制得更小,而不会丢失细节,但如果我没有设置分辨率,图像会在页面边界处被切断。