Sfoglia il codice sorgente

tif图片预览。根据 @gaoxingzaq 反馈和帮助,修改tif文件的jpg、pdf模式预览功能,兼容多页tif的pdf转换、jpg转换,以及jpg在线多页预览功能。

zhangzhen1979 3 anni fa
parent
commit
48f6a507dc

+ 40 - 39
server/src/main/java/cn/keking/service/impl/TiffFilePreviewImpl.java

@@ -2,7 +2,6 @@ package cn.keking.service.impl;
 
 import cn.keking.config.ConfigConstants;
 import cn.keking.model.FileAttribute;
-import cn.keking.model.FileType;
 import cn.keking.model.ReturnResponse;
 import cn.keking.service.FilePreview;
 import cn.keking.utils.ConvertPicUtil;
@@ -16,7 +15,6 @@ import org.springframework.util.StringUtils;
 import java.io.File;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.UUID;
 
 /**
  * tiff 图片文件处理
@@ -58,50 +56,53 @@ public class TiffFilePreviewImpl implements FilePreview {
 
         }else if("jpg".equalsIgnoreCase(tifPreviewType) || "pdf".equalsIgnoreCase(tifPreviewType)){
             String inputFileName = url.substring(url.lastIndexOf("/") + 1);
-            String inputFileExt = inputFileName.substring(inputFileName.lastIndexOf(".") + 1);
-            String uuid = UUID.randomUUID().toString().replaceAll("-","");
-            String tiffFileName = uuid + "." + inputFileExt;
-
-            ReturnResponse<String> response = DownloadUtils.downLoad(fileAttribute, tiffFileName);
-            if (response.isFailure()) {
-                return NOT_SUPPORTED_FILE_PAGE;
+            String inputFileNamePrefix = inputFileName.substring(0, inputFileName.lastIndexOf("."));
+
+            String strLocalTif = fileDir + inputFileName;
+            File fileTiff = new File(strLocalTif);
+            // 如果本地不存在这个tif文件,则下载
+            if(!fileTiff.exists()){
+                ReturnResponse<String> response = DownloadUtils.downLoad(fileAttribute, inputFileName);
+                if (response.isFailure()) {
+                    return NOT_SUPPORTED_FILE_PAGE;
+                }
             }
-            String strTiffPath = response.getContent();
-
-            File fileTiff = new File(strTiffPath);
 
-            File fileJpg = ConvertPicUtil.convertPic2Jpg(strTiffPath, fileDir + uuid + ".jpg");
-
-            if(fileJpg.exists()){
-                // 转换后的tif没用了,可以删掉了
-                if(fileTiff.exists()){
-                    fileTiff.delete();
+            String baseUrl = BaseUrlFilter.getBaseUrl();
+            if("pdf".equalsIgnoreCase(tifPreviewType)){
+                // 以PDF模式预览的过程
+                File filePdf = new File(fileDir + inputFileNamePrefix + ".pdf");
+                // 如果本地不存在对应的pdf,则调用转换过程。否则直接用现有的pdf文件
+                if(!filePdf.exists()){
+                    filePdf = ConvertPicUtil.convertTif2Pdf(strLocalTif, fileDir + inputFileNamePrefix + ".pdf");
                 }
 
-                String baseUrl = BaseUrlFilter.getBaseUrl();
-                if("pdf".equalsIgnoreCase(tifPreviewType)){
-                    File filePdf = ConvertPicUtil.convertJpg2Pdf(fileDir + uuid + ".jpg", fileDir + uuid + ".pdf");
-                    if(filePdf.exists()){
-                        String pdfUrl = baseUrl + uuid + ".pdf";
-                        model.addAttribute("pdfUrl", pdfUrl);
-
-                        return PDF_FILE_PREVIEW_PAGE;
-                    }
-                }else{
-                    String jpgUrl = baseUrl + uuid + ".jpg";
+                // 如果pdf已经存在,则将url路径加入到对象中,返回给页面
+                if(filePdf.exists()){
+                    String pdfUrl = baseUrl + inputFileNamePrefix + ".pdf";
+                    model.addAttribute("pdfUrl", pdfUrl);
 
-                    fileAttribute.setName(uuid + ".jpg");
-                    fileAttribute.setType(FileType.PICTURE);
-                    fileAttribute.setSuffix("jpg");
-                    fileAttribute.setUrl(jpgUrl);
-
-                    List<String> imgUrls = new ArrayList<>();
-                    imgUrls.add(jpgUrl);
-
-                    model.addAttribute("imgUrls", imgUrls);
-                    model.addAttribute("currentUrl", jpgUrl);
+                    return PDF_FILE_PREVIEW_PAGE;
+                }
+            }else{
+                // 以JPG模式预览的过程
+                String strJpgFilePathName = fileDir + inputFileNamePrefix + ".jpg";
+                // 将tif转换为jpg,返回转换后的文件路径、文件名的list
+                List<String> listPic2Jpg = ConvertPicUtil.convertTif2Jpg(strLocalTif, strJpgFilePathName);
+                // 将返回页面的图片url的list对象
+                List<String> listImageUrls = new ArrayList<>();
+                // 循环,拼装url的list对象
+                for(String strJpg : listPic2Jpg){
+                    listImageUrls.add(baseUrl + strJpg);
                 }
 
+                model.addAttribute("imgUrls", listImageUrls);
+                model.addAttribute("currentUrl", listImageUrls.get(0));
+            }
+
+            // 转换后的tif没用了,可以删掉了
+            if(fileTiff.exists()){
+                fileTiff.delete();
             }
 
             return PICTURE_FILE_PREVIEW_PAGE;

+ 166 - 34
server/src/main/java/cn/keking/utils/ConvertPicUtil.java

@@ -5,55 +5,129 @@ import com.lowagie.text.Document;
 import com.lowagie.text.Image;
 import com.lowagie.text.Rectangle;
 import com.lowagie.text.pdf.PdfWriter;
-import com.sun.media.jai.codec.ImageCodec;
-import com.sun.media.jai.codec.ImageEncoder;
-import com.sun.media.jai.codec.JPEGEncodeParam;
+import com.lowagie.text.pdf.RandomAccessFileOrArray;
+import com.lowagie.text.pdf.codec.TiffImage;
+import com.sun.media.jai.codec.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import javax.media.jai.JAI;
 import javax.media.jai.RenderedOp;
-import java.io.*;
+import java.awt.image.RenderedImage;
+import java.awt.image.renderable.ParameterBlock;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
 
 public class ConvertPicUtil {
 
+    private final static Logger logger = LoggerFactory.getLogger(ConvertPicUtil.class);
+
     /**
-     *  图片 转  JPG。
-     *  支持输入格式如下:BMP、GIF、FlashPix、JPEG、PNG、PMN、TIFF、WBMP
-     * @param strInputFile 输入文件的路径和文件名
+     * Tif 转  JPG。
+     * @param strInputFile  输入文件的路径和文件名
      * @param strOutputFile 输出文件的路径和文件名
-     * @return
+     * @return boolean 是否转换成功
      */
-    public static File convertPic2Jpg(String strInputFile, String strOutputFile) {
-        // 读取源图片文件
-        RenderedOp roInput = JAI.create("fileload", strInputFile);
+    public static List<String> convertTif2Jpg(String strInputFile, String strOutputFile) {
+        List<String> listImageFiles = new ArrayList<>();
+
+        if (strInputFile == null || "".equals(strInputFile.trim())) {
+            return null;
+        }
+        if (!new File(strInputFile).exists()) {
+            logger.info("找不到文件【" + strInputFile + "】");
+            return null;
+        }
+
+        strInputFile = strInputFile.replaceAll("\\\\", "/");
+        strOutputFile = strOutputFile.replaceAll("\\\\", "/");
+
+        FileSeekableStream fileSeekStream = null;
         try {
-            strOutputFile = strOutputFile.replaceAll("\\\\", "/");
-            File fileJpgPath = new File(strOutputFile.substring(0, strOutputFile.lastIndexOf("/")));
-            if(!fileJpgPath.exists()){
+            JPEGEncodeParam jpegEncodeParam = new JPEGEncodeParam();
+
+            TIFFEncodeParam tiffEncodeParam = new TIFFEncodeParam();
+            tiffEncodeParam.setCompression(TIFFEncodeParam.COMPRESSION_GROUP4);
+            tiffEncodeParam.setLittleEndian(false);
+
+            String strFilePrefix = strInputFile.substring(strInputFile.lastIndexOf("/") + 1, strInputFile.lastIndexOf("."));
+
+            fileSeekStream = new FileSeekableStream(strInputFile);
+            ImageDecoder imageDecoder = ImageCodec.createImageDecoder("TIFF", fileSeekStream, null);
+            int intTifCount = imageDecoder.getNumPages();
+            logger.info("该tif文件共有【" + intTifCount + "】页");
+
+            String strJpgPath = "";
+            String strJpgUrl = "";
+            if (intTifCount == 1) {
+                // 如果是单页tif文件,则转换的目标文件夹就在指定的位置
+                strJpgPath = strOutputFile.substring(0, strOutputFile.lastIndexOf("/"));
+            } else {
+                // 如果是多页tif文件,则在目标文件夹下,按照文件名再创建子目录,将转换后的文件放入此新建的子目录中
+                strJpgPath = strOutputFile.substring(0, strOutputFile.lastIndexOf("."));
+            }
+
+            // 处理目标文件夹,如果不存在则自动创建
+            File fileJpgPath = new File(strJpgPath);
+            if (!fileJpgPath.exists()) {
                 fileJpgPath.mkdirs();
             }
 
-            File fileJpg=new File(strOutputFile);
-            OutputStream ops = new FileOutputStream(fileJpg);
-            // 文件存储输出流
-            JPEGEncodeParam param = new JPEGEncodeParam();
-            ImageEncoder image = ImageCodec.createImageEncoder("JPEG", ops,
-                    param); // 指定输出格式
-            // 解析输出流进行输出
-            image.encode(roInput);
-            // 关闭流
-            ops.close();
-
-            return fileJpg;
-        } catch (FileNotFoundException e) {
-            e.printStackTrace();
-        } catch (Exception e) {
+            // 循环,处理每页tif文件,转换为jpg
+            for (int i = 0; i < intTifCount; i++) {
+                String strJpg = "";
+                if(intTifCount == 1){
+                    strJpg = strJpgPath + "/" + strFilePrefix + ".jpg";
+                    strJpgUrl = strFilePrefix + ".jpg";
+                }else{
+                    strJpg = strJpgPath + "/" + i + ".jpg";
+                    strJpgUrl = strFilePrefix + "/" + i + ".jpg";
+                }
+
+                File fileJpg = new File(strJpg);
+
+                // 如果文件不存在,则生成
+                if(!fileJpg.exists()){
+                    RenderedImage renderedImage = imageDecoder.decodeAsRenderedImage(i);
+                    ParameterBlock pb = new ParameterBlock();
+                    pb.addSource(renderedImage);
+                    pb.add(fileJpg.toString());
+                    pb.add("JPEG");
+                    pb.add(jpegEncodeParam);
+
+                    RenderedOp renderedOp = JAI.create("filestore", pb);
+                    renderedOp.dispose();
+
+                    logger.info("每页分别保存至: " + fileJpg.getCanonicalPath());
+                }else{
+                    logger.info("JPG文件已存在: " + fileJpg.getCanonicalPath());
+                }
+
+                listImageFiles.add(strJpgUrl);
+            }
+
+            return listImageFiles;
+        } catch (IOException e) {
             e.printStackTrace();
+            return null;
+        } finally {
+            if (fileSeekStream != null) {
+                try {
+                    fileSeekStream.close();
+                } catch (IOException e) {
+                }
+                fileSeekStream = null;
+            }
         }
-        return null;
     }
 
+
     /**
      * 将Jpg图片转换为Pdf文件
+     *
      * @param strJpgFile 输入的jpg的路径和文件名
      * @param strPdfFile 输出的pdf的路径和文件名
      * @return
@@ -61,7 +135,8 @@ public class ConvertPicUtil {
     public static File convertJpg2Pdf(String strJpgFile, String strPdfFile) {
         Document document = new Document();
         // 设置文档页边距
-        document.setMargins(0,0,0,0);
+        document.setMargins(0, 0, 0, 0);
+
         FileOutputStream fos = null;
         try {
             fos = new FileOutputStream(strPdfFile);
@@ -70,8 +145,8 @@ public class ConvertPicUtil {
             document.open();
             // 获取图片的宽高
             Image image = Image.getInstance(strJpgFile);
-            float floatImageHeight=image.getScaledHeight();
-            float floatImageWidth=image.getScaledWidth();
+            float floatImageHeight = image.getScaledHeight();
+            float floatImageWidth = image.getScaledWidth();
             // 设置页面宽高与图片一致
             Rectangle rectangle = new Rectangle(floatImageWidth, floatImageHeight);
             document.setPageSize(rectangle);
@@ -101,5 +176,62 @@ public class ConvertPicUtil {
         return null;
     }
 
-}
 
+    /**
+     * 将Tif图片转换为Pdf文件(支持多页Tif)
+     *
+     * @param strTifFile 输入的tif的路径和文件名
+     * @param strPdfFile 输出的pdf的路径和文件名
+     * @return
+     */
+    public static File convertTif2Pdf(String strTifFile, String strPdfFile) {
+        try {
+            RandomAccessFileOrArray rafa = new RandomAccessFileOrArray(strTifFile);
+
+            Document document = new Document();
+            // 设置文档页边距
+            document.setMargins(0, 0, 0, 0);
+
+            PdfWriter.getInstance(document, new FileOutputStream(strPdfFile));
+            document.open();
+            int intPages = TiffImage.getNumberOfPages(rafa);
+            Image image;
+            File filePDF;
+
+            if(intPages == 1){
+                String strJpg = strTifFile.substring(0, strTifFile.lastIndexOf(".")) + ".jpg";
+                File fileJpg = new File(strJpg);
+                List<String> listPic2Jpg = convertTif2Jpg(strTifFile, strJpg);
+
+                if(listPic2Jpg != null && fileJpg.exists()){
+                    filePDF = convertJpg2Pdf(strJpg, strPdfFile);
+                }
+
+            }else{
+                for (int i = 1; i <= intPages; i++) {
+                    image = TiffImage.getTiffImage(rafa, i);
+                    // 设置页面宽高与图片一致
+                    Rectangle pageSize = new Rectangle(image.getScaledWidth(), image.getScaledHeight());
+                    document.setPageSize(pageSize);
+                    // 图片居中
+                    image.setAlignment(Image.ALIGN_CENTER);
+                    //新建一页添加图片
+                    document.newPage();
+                    document.add(image);
+                }
+
+                document.close();
+            }
+
+            rafa.close();
+
+            filePDF = new File(strPdfFile);
+
+            return filePDF;
+        } catch (Exception e) {
+            System.out.println(e.toString());
+        }
+        return null;
+    }
+
+}