TIFF屬於一種高清圖片格式,分辨率很是高,在CKFinder上傳中會出現問題,查閱CF源碼發現使用ImageIO上傳圖片數據,通常的JPG等格式是徹底沒問題的,可是在上傳TIFF格式且提交較大時(達到1M以上就會報錯,可是其餘格式的徹底不會)會報錯內存溢出,但不是顯示具體錯誤信息。java
咱們先採用兩種方式解決問題:apache
第一種方式,就是修改CF的源代碼,在上傳TIFF格式圖片的時候,保留TIFF格式的圖片,同時將其轉換爲JPG格式的圖片,這個是沒有任何問題的。this
第二種方式,還沒有實現,須要解決CF縮略圖模式下TIFF不支持預覽問題。google
CKFinder版本:2.3url
WEB-INF/ckfinder.xml,添加tif格式,容許上傳tif格式圖片數據。spa
<type name="images"> <url>%BASE_URL%images/</url> <directory>%BASE_DIR%images</directory> <maxSize>100M</maxSize> <allowedExtensions>bmp,gif,jpeg,jpg,png,tif</allowedExtensions> <deniedExtensions></deniedExtensions> </type>
PS:目前只作簡單的處理,只能說勉強能用,後續再對第二種方法進行研究。code
/* * CKFinder * ======== * http://ckfinder.com * Copyright (C) 2007-2012, CKSource - Frederico Knabben. All rights reserved. * * The software, this file and its contents are subject to the CKFinder * License. Please read the license.txt file before using, installing, copying, * modifying or distribute this file or part of its contents. The contents of * this file is part of the Source Code of CKFinder. */ package com.ckfinder.connector.utils; import java.awt.Dimension; import java.awt.image.BufferedImage; import java.io.BufferedInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Arrays; import java.util.List; import javax.imageio.ImageIO; import javax.media.jai.JAI; import javax.media.jai.PlanarImage; import net.coobird.thumbnailator.Thumbnails; import org.apache.commons.fileupload.FileItem; import com.ckfinder.connector.configuration.IConfiguration; import com.sun.media.jai.codec.FileCacheSeekableStream; import com.sun.media.jai.codec.ImageCodec; import com.sun.media.jai.codec.ImageEncoder; import com.sun.media.jai.codec.JPEGEncodeParam; import com.sun.media.jai.codec.TIFFEncodeParam; /** * Utils to operate on images. */ public class ImageUtils { /** * allowed image extensions. */ private static final String[] ALLOWED_EXT = { "gif", "jpeg", "jpg", "png", "psd", "bmp", "tiff", "tif", "swc", "jpc", "jp2", "jpx", "jb2", "xbm", "wbmp" }; private static final int MAX_BUFF_SIZE = 1024; private static boolean prefix_tiff = false; /** * Resizes the image and writes it to the disk. * * @param sourceImage * orginal image file. * @param width * requested width * @param height * requested height * @param quality * requested destenation file quality * @param destFile * file to write to * @throws IOException * when error occurs. */ private static void resizeImage(final BufferedImage sourceImage, final int width, final int height, final float quality, final File destFile) throws IOException { try { Thumbnails.of(sourceImage).size(width, height).keepAspectRatio(false) .outputQuality(quality).toFile(destFile); // for some special files outputQuality couses error: //IllegalStateException inner Thumbnailator jar. When exception is thrown // image is resized without quality // When http://code.google.com/p/thumbnailator/issues/detail?id=9 // will be fixed this try catch can be deleted. Only: //Thumbnails.of(sourceImage).size(width, height).keepAspectRatio(false) // .outputQuality(quality).toFile(destFile); // should remain. } catch (IllegalStateException e) { Thumbnails.of(sourceImage).size(width, height).keepAspectRatio(false) .toFile(destFile); } } /** * create thumb file. * * @param orginFile * orgin image file. * @param file * file to save thumb * @param conf * connector configuration * @throws IOException * when error occurs. */ public static void createThumb(final File orginFile, final File file, final IConfiguration conf) throws IOException { BufferedImage image = ImageIO.read(orginFile); if (image != null) { Dimension dimension = createThumbDimension(image, conf.getMaxThumbWidth(), conf.getMaxThumbHeight()); FileUtils.createPath(file, conf, true); if (image.getHeight() == dimension.height && image.getWidth() == dimension.width) { writeUntouchedImage(orginFile, file); } else { resizeImage(image, dimension.width, dimension.height, conf.getThumbsQuality(), file); } } else { if (conf.isDebugMode()) { throw new IOException("Wrong image file"); } } } /** * Uploads image and if the image size is larger than maximum allowed it * resizes the image. * * @param stream * input stream. * @param file * file name * @param fileName * name of file * @param conf * connector configuration * @throws IOException * when error occurs. * 20180105 update method - upload 2 files, one of JPEG, one of TIFF */ public static void createTmpThumb(final InputStream stream, final File file, final String fileName, final IConfiguration conf) throws IOException { if(prefix_tiff){ // System.out.println(file.getAbsolutePath()); // System.out.println(file.getAbsolutePath().substring(0, file.getAbsolutePath().lastIndexOf("."))); FileCacheSeekableStream stream1 = new FileCacheSeekableStream(stream); PlanarImage in = JAI.create("stream", stream1); String newFilePath = file.getAbsolutePath().substring(0, file.getAbsolutePath().lastIndexOf(".")) + ".jpg"; OutputStream osJPEG = new FileOutputStream(newFilePath); JPEGEncodeParam JPEGparam = new JPEGEncodeParam(); ImageEncoder encJPEG = ImageCodec.createImageEncoder("JPEG", osJPEG, JPEGparam); OutputStream osTIFF = new FileOutputStream(file); TIFFEncodeParam TIFFparam = new TIFFEncodeParam(); TIFFparam.setCompression(TIFFEncodeParam.COMPRESSION_NONE); ImageEncoder encTIFF = ImageCodec.createImageEncoder("TIFF", osTIFF, TIFFparam); try { encJPEG.encode(in); osJPEG.flush(); osJPEG.close(); encTIFF.encode(in); osTIFF.flush(); osTIFF.close(); stream.close(); } catch (IOException e) { throw new IOException("Wrong file"); } } else { BufferedInputStream bufferedIS = new BufferedInputStream(stream); bufferedIS.mark(Integer.MAX_VALUE); BufferedImage image = ImageIO.read(bufferedIS); if (image == null) { throw new IOException("Wrong file"); } Dimension dimension = createThumbDimension(image, conf.getImgWidth(), conf.getImgHeight()); if (image.getHeight() == dimension.height && image.getWidth() == dimension.width) { bufferedIS.reset(); writeUntouchedImage(bufferedIS, file); } else { resizeImage(image, dimension.width, dimension.height, conf.getImgQuality(), file); } stream.close(); } } /** * Creates image file with fixed width and height. * * @param sourceFile * input file * @param destFile * file to save * @param width * image width * @param height * image height * @param quality * image quality * @throws IOException * when error occurs. */ public static void createResizedImage(final File sourceFile, final File destFile, final int width, final int height, final float quality) throws IOException { BufferedImage image = ImageIO.read(sourceFile); Dimension dimension = new Dimension(width, height); if (image.getHeight() == dimension.height && image.getWidth() == dimension.width) { writeUntouchedImage(sourceFile, destFile); } else { resizeImage(image, dimension.width, dimension.height, quality, destFile); } } /** * creates dimension of thumb. * * @param image * orginal image. * @param maxWidth * max thumb width * @param maxHeight * max thumb height * @return dimension of thumb image. */ private static Dimension createThumbDimension(final BufferedImage image, final int maxWidth, final int maxHeight) { Dimension dimension = new Dimension(); if (image.getWidth() >= image.getHeight()) { if (image.getWidth() >= maxWidth) { dimension.width = maxWidth; dimension.height = Math.round(((float) maxWidth / image .getWidth()) * image.getHeight()); } else { dimension.height = image.getHeight(); dimension.width = image.getWidth(); } } else { if (image.getHeight() >= maxHeight) { dimension.height = maxHeight; dimension.width = Math.round((((float) maxHeight / image .getHeight()) * image.getWidth())); } else { dimension.height = image.getHeight(); dimension.width = image.getWidth(); } } return dimension; } /** * checks if file is image. * * @param file * file to check * @return true if file is image. */ public static boolean isImage(final File file) { List<String> list = Arrays.asList(ALLOWED_EXT); String fileExt = null; if (file != null) { fileExt = FileUtils.getFileExtension(file.getName().toLowerCase()); return (fileExt != null) ? list.contains(fileExt) : false; } else { return false; } } /** * check if image size isn't bigger then bigest allowed. * * @param stream * temp file input stream. * @param conf * connector configuration. * @return true if image size isn't bigger then bigest allowe. * @throws IOException * when error occurs during reading image. */ public static boolean checkImageSize(final InputStream stream, final IConfiguration conf) throws IOException { if(!prefix_tiff){ BufferedImage bi = ImageIO.read(stream); stream.close(); if (bi == null) { return false; } if (bi.getHeight() > conf.getImgHeight() || bi.getWidth() > conf.getImgWidth()) { return false; } } return true; } /** * checks if image file is image. * * @param item * file upload item * @return true if file is image. */ public static boolean checkImageFile(final FileItem item) { BufferedImage bi; InputStream is = null; if(item.getContentType().equals("image/tiff")){ prefix_tiff = true; return true; } else { prefix_tiff = false; try { is = item.getInputStream(); bi = ImageIO.read(is); } catch (IOException e) { return false; } finally { if (is != null){ try { is.close(); } catch (Exception e) {} } } return (bi != null); } } /** * writes unchanged file to disk. * * @param sourceFile * - file to read from * * @param destFile * - file to write to * * @throws IOException * when error occurs. */ private static void writeUntouchedImage(final File sourceFile, final File destFile) throws IOException { FileInputStream fileIS = new FileInputStream(sourceFile); writeUntouchedImage(fileIS, destFile); } /** * writes unchanged file to disk. * * @param stream * - stream to read the file from * * @param destFile * - file to write to * * @throws IOException * when error occurs. */ private static void writeUntouchedImage(final InputStream stream, final File destFile) throws IOException { ByteArrayOutputStream byteArrayOS = new ByteArrayOutputStream(); byte[] buffer = new byte[MAX_BUFF_SIZE]; int readNum = -1; while ((readNum = stream.read(buffer)) != -1) { byteArrayOS.write(buffer, 0, readNum); } byte[] bytes = byteArrayOS.toByteArray(); byteArrayOS.close(); FileOutputStream fileOS = new FileOutputStream(destFile); fileOS.write(bytes); fileOS.flush(); fileOS.close(); } }