Java tif多页文件转jpg问题,Decoding of old style JPEG-in-TIFF data is not supported问题

Tiff文件转jpg图片有多种做法,网上大多数是采用java的JAI,其实还可以采用jdk自带的imageio进行解析转换。

方法一:
采用JAI
首先需要引入JAI的jar包,有:jai_codec.jar,jai_core.jar
具体实现方法:

一、Tiff文件转换为单张图片

 RenderedOp src2 = JAI.create("fileload", “./file.tif”);//读取tiff文件
     OutputStream os2 = new FileOutputStream(path+"/test/fk.jpg"); //文件存储输出流
     JPEGEncodeParam param = new JPEGEncodeParam();
     ImageEncoder enc2 = ImageCodec.createImageEncoder("JPEG", os2, param); //指定输出格式
     enc2.encode(src2 );//解析输出流进行输出
     os2.close();

二、tiff多页文件转为多张图片
import java.awt.image.RenderedImage;
import java.awt.image.renderable.ParameterBlock;
import java.io.File;
import java.io.IOException;

import javax.media.jai.JAI;
import javax.media.jai.RenderedOp;

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.JPEGEncodeParam;
import com.sun.media.jai.codec.TIFFDecodeParam;
import com.sun.media.jai.codec.TIFFEncodeParam;


public class TestTiffToJPEG {
	
	public static void main(String[] args){
		tiffToJPEG("F:\\Workspace\\exoa\\oadoc\\test\\tiffile\\testfile.tif");
	}
	
	public static void tiffToJPEG(String tiff){
        FileSeekableStream ss = null;
		try {
			ss = new FileSeekableStream(tiff);//以流形式取出tif文件数据
		} catch (IOException e) {
			System.out.println("Exception in " + tiff + " " + e.getMessage());
			e.printStackTrace();
		}
		String path,tiffName;
		path = tiff.substring(0, tiff.lastIndexOf("."));
		tiffName = tiff.substring(tiff.lastIndexOf("\\"),tiff.lastIndexOf("."));
        TIFFDecodeParam param0 = null;
        TIFFEncodeParam param = new TIFFEncodeParam();
        JPEGEncodeParam param1 = new JPEGEncodeParam();
        if(ss!=null){
        	ImageDecoder dec = ImageCodec.createImageDecoder("tiff", ss, param0);//将tif文件流转为image图片
        	int count = 0;
        	try {
        		count = dec.getNumPages();//tif文件页数
        	} catch (IOException e) {
        		System.out.println("Exception in dec.getNumPages() " + e.getMessage());
        		e.printStackTrace();
        	}
        	param.setCompression(TIFFEncodeParam.COMPRESSION_GROUP4);
        	param.setLittleEndian(false); // Intel
        	System.out.println("This TIF has " + count + " image(s)");
        	for (int i = 0; i < count; i++) {//存储为jpeg图片
        		
        		RenderedImage page = null;
        		File f = new File(path,"\\"+tiffName+"_" + i + ".jpg");
				try {
					page = dec.decodeAsRenderedImage(i);//取出第i张image图片
					if(!f.exists()){
						f.getParentFile().mkdirs();
						f.createNewFile();
					}
				} catch (IOException e) {
					System.out.println("Exception in File f or dec.decodeAsRenderedImage(i)" + e.getMessage());
					e.printStackTrace();
				}
				if(f.exists() && page != null){//压缩图片并保存为JPEG格式
					ParameterBlock pb = new ParameterBlock();
					pb.addSource(page);
					pb.add(f.toString());
					pb.add("JPEG");
					pb.add(param1);
					RenderedOp r = JAI.create("filestore",pb);
					r.dispose();
				}
        	}
        }
	}
}
以上为java的JAI对tif文件处理为jpg图片,可适用于大部分tif文件,但若是由doc文件转换过来的tif文件,在解析图片时会出现下标越界异常,只能用于针对扫描出来的tif扫描件。

注:java的JAI暂时还不支持对旧式JPEG-in-TIFF数据的解码,也就是,部分tif文件执行此段代码进行解析时,会报异常:Decoding of old style JPEG-in-TIFF data is not supported

为了解决这个问题,本人在网上大幅度搜罗,发现可以采取另一种方法对tif进行解析转换。

采用JDK自带的imageio对tif进行转换,此种方法不仅可以适应旧式JPEG-in-TIFF数据,需引用jai-imageio-core-1.3.1.jar,实现方式也相对于上两种简洁,具体实现如下

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

import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;

public class TiffToJPEGByImageIO {
	public static void main(String[] args){
		tiffToJPEGByImageIO("F:\\Workspace\\exoa\\oadoc\\test\\tiffile\\1.tif");
	}

	private static void tiffToJPEGByImageIO(String tiff) {
		ImageInputStream input;
		try {
			input = ImageIO.createImageInputStream(new File(tiff));//以图片输入流形式读取到tif
		    // Get the reader
		    ImageReader reader = ImageIO.getImageReaders(input).next();//获得image阅读器,阅读对象为tif文件转换的流
		    String path,tiffName;
			path = tiff.substring(0, tiff.lastIndexOf("."));
			tiffName = tiff.substring(tiff.lastIndexOf("\\"),tiff.lastIndexOf("."));
		    try {
		        reader.setInput(input);
		        // Read page 2 of the TIFF file
		        int count = reader.getNumImages(true);//tif文件页数
		        //System.out.println(count);
		        for(int i = 0; i < count; i++){
		        	BufferedImage image = reader.read(i, null);//取得第i页
		        	File f = new File(path,"\\"+tiffName+"_"+i+".jpg");
		        	try {
		        		if(!f.exists()){
		        			f.getParentFile().mkdirs();
		        			f.createNewFile();
		        		}
		        	} catch (IOException e) {
		        		e.printStackTrace();
		        	}
		        	ImageIO.write(image, "JPEG", f);//保存图片
		        }
		    }
		    finally {
		        reader.dispose();
		        input.close();
		    }
		}catch (IOException e) {
			e.printStackTrace();
		}
	}
}



猜你喜欢

转载自blog.csdn.net/u014773389/article/details/72279693
old