近期项目需要在前端展示 tif 格式的图片,测试发现只有在 ie9以上浏览器及苹果的 Safari 浏览器上能自带支持查看 tif 图片,然而最常用的 Google Chrome浏览器上并不能正常显示。
查了各种资料后自己写了一份实现,欢迎借鉴。
public class TifFile extends FileProcess {
@Override
public byte[] tif2JPG(byte[] buffer, InputStream inputStream, String outputFilePath) throws Exception {
if(buffer==null||buffer.length==0) return null;
byte[] byt = null;
String jpgOutFilePath = outputFilePath.replaceAll(".tif", ".jpg");
File jpgFile = new File(jpgOutFilePath);
if (jpgFile.exists()) {
InputStream input = new FileInputStream(jpgFile);
byt = new byte[input.available()];
input.read(byt);
input.close();
return byt;
}
BufferedImage bufferedImage = ImageIO.read(inputStream);
// 指定写图片的方式为 jpg
ImageWriter imgWrier = ImageIO.getImageWritersByFormatName("jpeg").next();
ImageWriteParam imgWriteParams = new javax.imageio.plugins.jpeg.JPEGImageWriteParam(null);
// 要使用压缩,必须指定压缩方式为MODE_EXPLICIT
imgWriteParams.setCompressionMode(imgWriteParams.MODE_EXPLICIT);
// 这里指定压缩的程度,参数qality是取值0~1范围内,
imgWriteParams.setCompressionQuality(0.5f);
imgWriteParams.setProgressiveMode(imgWriteParams.MODE_DISABLED);
ColorModel colorModel = ColorModel.getRGBdefault();
// 指定压缩时使用的色彩模式
imgWriteParams.setDestinationType(new javax.imageio.ImageTypeSpecifier(colorModel, colorModel
.createCompatibleSampleModel(16, 16)));
ByteArrayOutputStream bos = new ByteArrayOutputStream(buffer.length);
imgWrier.reset();
// 必须先指定 out值,才能调用write方法, ImageOutputStream可以通过任何 OutputStream构造
imgWrier.setOutput(ImageIO.createImageOutputStream(bos));
// 调用write方法,就可以向输入流写图片
imgWrier.write(null, new IIOImage(bufferedImage, null, null), imgWriteParams);
bos.flush();
bos.close();
inputStream.close();
byte[] result = bos.toByteArray();
outputStreamFile(result,jpgFile);
return result;
}
public void outputStreamFile(byte[] buffer,File file) throws Exception {
OutputStream os = new FileOutputStream(file);
os.write(buffer);
os.close();
}
}
public class FileProcessUtils {
public static byte[] convertToJPG(Class<?> clazz, byte[] buffer,InputStream inputStream,String outFilePath,String extension) {
byte[] byt = null;
try {
FileProcess file = (FileProcess) Class.forName(clazz.getName()).newInstance();
if("tif".equals(extension)) {
byt = file.tif2JPG(buffer, inputStream, outFilePath);
}
} catch (Exception e) {
System.out.println(e.getMessage());
}
return byt;
}
public static void main(String[] args) throws Exception {
FileInputStream fis = new FileInputStream("/Users/HJK/Downloads/abcdef.tif");
byte[] buffer = new byte[fis.available()];
fis.read(buffer);
InputStream inputStream = new ByteArrayInputStream(buffer);
convertToJPG(TifFile.class,buffer, inputStream, "/Users/HJK/Downloads/abcdef.jpg","tif");
}
}
画个重点,这里需要用到 jai-imageio-core 这个包,如果缺少这个包会导致
BufferedImage bufferedImage = ImageIO.read(inputStream);
读取的 BufferedImage 是个空对象,后边会出现参数异常。具体原因因为项目时间紧,暂时没有深入研究,猜测应该是jai-imageio的作者对 ImageIO 做了一些读取 tif 的完善。