原文地址:Java操作tif文件
參考資料: 使用IIOImage對象寫出一個多頁圖片
最近一段時間,公司需要對原來的tif文檔做合併處理,也有的是之前的拆分程序出問題,需要重新拆分;
從網上找了一天的資料,終於把問題解決了;
上面的鏈接中的代碼有部分地方需要修改:
拆分一個多頁的tiff爲單個tif:
/**
* 從一個分頁的tiff文件中拆分各頁,並從0開始命名每一頁
* @param fTiff 源tiff文件
* @param decDir
* tiff目標路徑,目標文件將會以0001.tif,0002.tif...置於此路徑下
* @return true表示成功,false表示失敗
*/
public static boolean makeSingleTif(File fTiff, File decDir) {
boolean bres = true;
FileImageInputStream fis = null;
try {
//java1.8的ImageIO不支持原文中以"TIFF"名字獲取ImageReader,具體原因是
//ImageReaderSpi中有一個註冊器,會先在內存中註冊各個名稱的讀取器,而這個註冊器恰好沒有TIFF格式的
//所以需要jai-imageio-1.1.jar提供TIFFImageReader;
TIFFImageReaderSpi tiffImageReaderSpi = new TIFFImageReaderSpi();
TIFFImageReader tiffImageReader = new TIFFImageReader(tiffImageReaderSpi);
fis = new FileImageInputStream(fTiff);
tiffImageReader.setInput(fis);
int numPages = tiffImageReader.getNumImages(true);
for(int i=0; i<numPages; i++) {
BufferedImage bi = tiffImageReader.read(i);
File tif = new File(decDir.getPath() + File.separator
+ String.format(""+i) + ".tif");
//此處我註銷了原文中的寫Tiff文件的方法其原因是如果採用此方法會導致個別圖片拆不出來,所以改用ImageWriter,個人推測是因爲原文采用的方式涉及到圖片的每個像素
// bres = createTiff(tif,new RenderedImage[]{bi},dpiData,false);
//TIFFImageWriter與reader是同樣的原理;
FileImageOutputStream fios = new FileImageOutputStream(tif);
TIFFImageWriterSpi tiffImageWriterSpi = new TIFFImageWriterSpi();
TIFFImageWriter tiffImageWriter = new TIFFImageWriter(tiffImageWriterSpi);
tiffImageWriter.setOutput(fios);
tiffImageWriter.write(bi);
}
} catch (Exception e) {
e.printStackTrace();
bres = false;
}finally {
if (fis != null) {
try {
fis.flush();
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return bres;
}
合併多個tiff爲一個多頁tiff:
/**
* 合併多個Tiff文件成一個多頁Tiff文件
*
* @param fTiff
* 目標tiff文件
* @param tifDir
* 源tiff文件路徑,tiff文件必須以0001.tif,0002.tif...置於此路徑下
* @return true表示成功,false表示失敗
*/
static public boolean mergeTiff(File fTiff, File tifDir) {
boolean bres = true;
//tiff格式的圖片讀取器;
TIFFImageReader tiffImageReader = new TIFFImageReader(new TIFFImageReaderSpi());
FileImageInputStream fis = null;
//map用於保存數字格式的文件名爲key,以保證合併後的順序正確
Map<String,BufferedImage> biMap = new HashMap<>();
File[] fs = tifDir.listFiles();
for(File f: fs) {
String fileName = f.getName();
if(!fileName.endsWith(".tif")) {
continue;
}
String key = fileName.replace(".tif","");
if(isNum(key)){
try {
fis = new FileImageInputStream(f);
tiffImageReader.setInput(fis);
biMap.put(key,tiffImageReader.read(0));
}catch (Exception e) {
e.printStackTrace();
}finally {
if(tiffImageReader != null) {
tiffImageReader.dispose();
}
if (fis != null) {
try {
fis.flush();
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
//tiff格式圖片輸出流
TIFFImageWriter tiffImageWriter = new TIFFImageWriter(new TIFFImageWriterSpi());
try {
//先指定一個文件用於存儲輸出的數據
tiffImageWriter.setOutput(new FileImageOutputStream(fTiff));
//指定第一個tif文件寫到指定的文件中
BufferedImage bufferedImage_0 = biMap.get("0");
//IIOImage類是用於存儲 圖片/縮略圖/元數據信息 的引用類
IIOImage iioImage_0 = new IIOImage(bufferedImage_0, null, null);
//write方法,將給定的IIOImage對象寫到文件系統中;
tiffImageWriter.write(null,iioImage_0,null);
for (int i = 1; i < biMap.size(); i++) {
//判斷該輸出流是否可以插入新圖片到文件系統中的
if(tiffImageWriter.canInsertImage(i)){
//根據順序獲取緩衝中的圖片;
BufferedImage bufferedImage = biMap.get(String.valueOf(i));
IIOImage iioImage = new IIOImage(bufferedImage, null, null);
//將文件插入到輸出的多圖片文件中的指定的下標處
tiffImageWriter.writeInsert(i, iioImage,null);
}
}
bres = true;
} catch (IOException e) {
e.printStackTrace();
bres = false;
}finally {
return bres;
}
}
public static void main(String[] args) {
boolean num = isNum("123");
System.out.println(num);
}
//如果能轉成bigdecimal則表示是數字
private static boolean isNum(String name){
try{
if(!name.contains(".")){
BigDecimal bigDecimal = new BigDecimal(name);
return true;
}else{
return false;
}
}catch (Exception e){
return false;
}
}
jar包下載: