前几天老大让我做一个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思想可以稍微修改一下,就是从一个目录里面读取所以图片就行,我还没写 呵呵,改天试一下,弄好再传上来。