前几天老大让我做一个java print tiff格式图片的程序,而我对这个一无所知,幸好老大给我了些资料。刚开始只能做到把tiff图片分解成功,并单页打印,没办法实现多页连续打印,由于我对java Printable 这个类不是很了解,所以在哪个循环的地方控制不好,无法实现多页连续打印。但为了完成任务,我想办法把tiff图片文件转化成为了pdf文件,但是pdf文件在java中也不容易打印,所以我只好调用Adobe Reader 的打印程序打印,但是这个不是很好,需要客户装Adobe Reader 才行。后来经过老大稍微修改,实现了多页打印。后来发现其实我对哪个Printtable 里面的哪个pageIndex参数没有理解。
程序中需要的jar文件:jai_codec.jar;jai_core.jar;iText-2.1.3.jar(自己网上下吧,我也是自己找的,网址没有记下来);需要安装 jai_imageio插件(https://jai-imageio.dev.java.net/binary-builds.html);
java 直接连续打印tiff 程序:
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.awt.image.renderable.ParameterBlock;
import java.awt.print.PageFormat;
import java.awt.print.Paper;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import java.io.File;
import java.util.Vector;
import javax.imageio.ImageReader;
import javax.imageio.spi.IIORegistry;
import javax.imageio.spi.ImageReaderSpi;
import javax.imageio.stream.FileImageInputStream;
import javax.imageio.stream.ImageInputStream;
import javax.media.jai.JAI;
import javax.media.jai.PlanarImage;
import javax.media.jai.RenderedOp;
import com.sun.media.jai.codec.FileSeekableStream;
import com.sun.media.jai.codec.SeekableStream;
import com.sun.media.jai.codec.TIFFDecodeParam;
import com.sun.media.jai.codec.TIFFDirectory;
public class PrintTiff {
private BufferedImage[] bi = null;
private File tiffFile = null;
private int pages = 0;
public static void main(String[] args) throws Exception {
PrintTiff pt = new PrintTiff("3699_001.tif");//自己的tiff文件,我是把它放在程序的同一个目录下面
pt.print();
}
public PrintTiff(String file) {
tiffFile = new File(file);
init();
}
private void init() {
try {
ImageReader tiffReader;
ImageInputStream input;
input = new FileImageInputStream(tiffFile);
//以下为读取tiff文件
IIORegistry iioreg = IIORegistry.getDefaultInstance();
iioreg.registerApplicationClasspathSpis();
ImageReaderSpi irs = new com.sun.media.imageioimpl.plugins.tiff.TIFFImageReaderSpi();
tiffReader = irs.createReaderInstance();
tiffReader.setInput(input);
//获取tiff文件的页数
pages = tiffReader.getNumImages(true);
if (pages > 0) {
bi = new BufferedImage[pages];
for (int i = 0; i < pages; i++) {
//把每一页放入 BufferedImage[]数组
bi[i] = tiffReader.read(i, null);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void print() throws PrinterException {
PrinterJob job = PrinterJob.getPrinterJob();
PageFormat format = job.defaultPage();
double inch = 72;
Paper paper = format.getPaper();
paper.setImageableArea(inch, inch, paper.getWidth() - 2 * inch, paper
.getHeight()
- 2 * inch);
format.setPaper(paper);
MyPrintable p = new MyPrintable();
job.setPrintable(p);
if (job.printDialog()) {
job.print();
}
}
private class MyPrintable implements Printable {
public int print(Graphics graphics, PageFormat pageFormat, int pageIndex)
throws PrinterException {
if (pageIndex == pages) {
return NO_SUCH_PAGE;
}
graphics.translate((int) pageFormat.getImageableX(),
(int) pageFormat.getImageableY());
//打印每一页。关键在于bi[pageIndex],我当时对pageIndex不明白,不知道它是怎么循环取值的,所以开始的想法//是把bi[i]整合到一个文件里面去再打印。
graphics.drawImage(bi[pageIndex], 0, 0, 450, 650, null);
return PAGE_EXISTS;
}
}
}
下面是我做的把tiff转化为pdf后调用Adobe Reader 打印程序打印的。虽然没多大作用,但是我发现转化后的打印格式似乎比直接打印tiff好看些,而且质量也不差。就当作学习吧。
package example;
import java.awt.image.BufferedImage;
import java.awt.image.Raster;
import java.awt.image.RenderedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Hashtable;
import javax.print.Doc;
import javax.print.DocFlavor;
import javax.print.DocPrintJob;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.ServiceUI;
import javax.print.SimpleDoc;
import javax.print.attribute.DocAttributeSet;
import javax.print.attribute.HashDocAttributeSet;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import com.lowagie.text.Document;
import com.lowagie.text.Image;
import com.lowagie.text.pdf.PdfContentByte;
import com.lowagie.text.pdf.PdfWriter;
import com.sun.media.jai.codec.FileSeekableStream;
import com.sun.media.jai.codec.ImageCodec;
import com.sun.media.jai.codec.ImageDecoder;
import com.sun.media.jai.codec.SeekableStream;
import com.sun.media.jai.codec.TIFFDirectory;
import com.sun.media.jai.codecimpl.TIFFImageDecoder;
public class TiffToPDF {
Document document;
PdfContentByte cb;
public TiffToPDF(String filename, String[] strImages) throws Exception {
document = new Document();
FileOutputStream rech = new FileOutputStream(filename);
PdfWriter writer = PdfWriter.getInstance(document, rech);
document.open();
cb = writer.getDirectContent();
for (int i = 0; i < strImages.length; ++i) {
addImage(strImages[i]);
}
document.close();
}
public void addImage(String strImageName) throws Exception {
System.out.println(strImageName);
File file = new File(strImageName);
SeekableStream stream = new FileSeekableStream(strImageName);
TIFFDirectory dir = new TIFFDirectory(stream, 0);
String[] names = ImageCodec.getDecoderNames(stream);
ImageDecoder dec = ImageCodec
.createImageDecoder(names[0], stream, null);
int total = dec.getNumPages();
for (int k = 0; k < total; ++k) {
RenderedImage ri = dec.decodeAsRenderedImage(k);
Raster ra = ri.getData();
BufferedImage bi = new BufferedImage(ri.getColorModel(), Raster
.createWritableRaster(ri.getSampleModel(), ra
.getDataBuffer(), null), false, new Hashtable());
Image img = Image.getInstance(bi, null, true);
long h = 0;
long w = 0;
long IFDOffset = dir.getIFDOffset();
while (IFDOffset != 0L) {
dir = new TIFFDirectory(stream, IFDOffset, 0);
IFDOffset = dir.getNextIFDOffset();
h = dir.getFieldAsLong(TIFFImageDecoder.TIFF_IMAGE_LENGTH);
w = dir.getFieldAsLong(TIFFImageDecoder.TIFF_IMAGE_WIDTH);
}
float percent = 100;
int pos = 0;
if (w > 895)
percent = ((595 + 18) * 100 / w);
if (h > 842)
pos = (int) (842 - h * percent / 100);
else
pos = (int) (842 - h);
System.out.println(percent);
System.out.println(pos);
img.scalePercent(percent);
img.setAbsolutePosition(0, pos);
System.out.println("Image: " + k);
cb.addImage(img);
document.newPage();
}
stream.close();
// file.delete();
}
public static void print() {
/****
这一段本来是想调用java自带的打印程序打印pdf的,但是行不通,问朋友都说用其他的插件打,
我一个同事以前自己用vb做了个打印pdf的exe文件,但是传进去的是他自己的特定参数,我不方便调用。
在佩服他能用vb做一个自己需要的exe文件
************/
// File file = new File("test.txt");// 获取选择的文件
// // 构建打印请求属性集
// PrintRequestAttributeSet pras = new HashPrintRequestAttributeSet();
// // 设置打印格式,因为未确定文件类型,这里选择AUTOSENSE
// DocFlavor flavor = DocFlavor.INPUT_STREAM.PDF;
// // 查找所有的可用打印服务
// PrintService printService[] = PrintServiceLookup.lookupPrintServices(
// flavor, pras);
// // 定位默认的打印服务
// PrintService defaultService = PrintServiceLookup
// .lookupDefaultPrintService();
// // 显示打印对话框
// PrintService service = ServiceUI.printDialog(null, 200, 200,
// printService, defaultService, flavor, pras);
// if (service != null) {
// try {
// DocPrintJob job = service.createPrintJob();// 创建打印作业
// FileInputStream fis = new FileInputStream(file);// 构造待打印的文件流
// DocAttributeSet das = new HashDocAttributeSet();
// Doc doc = new SimpleDoc(fis, flavor, das);// 建立打印文件格式
// job.print(doc, pras);// 进行文件的打印
// } catch (Exception e) {
// e.printStackTrace();
// }
// }
/
//以下是打印
String sysName = System.getProperty("os.name");
String exeName = "start";
if (sysName.startsWith("Windows")) {
if (exeName.equals("start")) {
Runtime rn = Runtime.getRuntime();
try {
String cmd[] = {
"D:\\Program Files\\Adobe\\Reader 8.0\\Reader\\AcroRd32.exe",
"temp.pdf" };
Process p = Runtime.getRuntime().exec(
"cmd.exe /C start acrord32.exe /p" + "./temp.pdf");
BufferedReader in = new BufferedReader(
new InputStreamReader(p.getInputStream()));
String line = null;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
exeName = "stop";
} catch (IOException e) {
e.printStackTrace();
}
} else if (exeName.equals("stop")) {
try {
Runtime.getRuntime().exec(
"cmd.exe /c taskkill /im acrord32.exe /f");
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
try {
String[] temp = { "3699_001.tif" };
TiffToPDF build = new TiffToPDF("temp.pdf", temp);
print();
} catch (Exception e) {
e.printStackTrace();
}
}
}
这个打印在网上的资料似乎很少,所以写出来希望有帮助。批量打印图片应该根据打印tiff思想可以稍微修改一下,就是从一个目录里面读取所以图片就行,我还没写 呵呵,改天试一下,弄好再传上来。