需求:工作中经常遇到显示图片的,有时还需要预览进行放大处理,有时需要一次性展示很多图片,如果图片过大会造成加载过慢。性能极差。
1工具
import java.awt.Graphics;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.HeadlessException;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.swing.ImageIcon;
public class FileText {
public static void main(String[] args) {
// String path = ; // 要遍历的路径
// File file = ; // 获取其file对象
func(new File("C:\\usr\\local\\app\\buscredit\\buscredit\\uploadfile\\contentfile"));
System.out.println("========");
System.out.println("压缩完毕");
System.out.println("========");
}
private static void func(File file) {
File[] fs = file.listFiles();
for (File f : fs) {
if (f.isDirectory()) // 若是目录,则递归打印该目录下的文件
func(f);
if (f.isFile()&&f.getName().indexOf("_small")==-1) {// 若是文件,直接打印
if(f.getName().endsWith("BMP") || f.getName().endsWith("JPG") || f.getName().endsWith("JPEG")|| f.getName().endsWith("PNG")|| f.getName().endsWith("GIF") || f.getName().endsWith("bmp") || f.getName().endsWith("jpg") || f.getName().endsWith("jpeg")|| f.getName().endsWith("png")|| f.getName().endsWith("gif")) {
if(isimg(f)) {
System.out.println("f=="+f);
try {
compressPic(f.getPath());
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println(f.getName()+"---压缩失败");
}
}
}
}
}
}
public static File compressPic(String srcFilePath) throws IOException {
File file = null;
BufferedImage src = null;
FileOutputStream out = null;
ImageWriter imgWrier;
ImageWriteParam imgWriteParams;
// 指定写图片的方式为 jpg
imgWrier = ImageIO.getImageWritersByFormatName("jpg").next();
imgWriteParams = new javax.imageio.plugins.jpeg.JPEGImageWriteParam(null);
// 要使用压缩,必须指定压缩方式为MODE_EXPLICIT
imgWriteParams.setCompressionMode(imgWriteParams.MODE_EXPLICIT);
// 这里指定压缩的程度,参数qality是取值0~1范围内,值越小,压缩出来图片越小
imgWriteParams.setCompressionQuality((float) 0.1);
imgWriteParams.setProgressiveMode(imgWriteParams.MODE_DISABLED);
ColorModel colorModel = ImageIO.read(new File(srcFilePath)).getColorModel();
imgWriteParams.setDestinationType(
new javax.imageio.ImageTypeSpecifier(colorModel, colorModel.createCompatibleSampleModel(16, 16)));
if (isBlank(srcFilePath)) {
return null;
} else {
file = new File(srcFilePath);
System.out.println(file.length());
src=BufferedImageBuilder.toBufferedImage(Toolkit.getDefaultToolkit().getImage(file.getPath()));
// src = ImageIO.read(file);
File destFile = new File(file.getPath().substring(0, file.getPath().lastIndexOf(".")) + "_small"+file.getName().substring(file.getName().lastIndexOf(".")));
out = new FileOutputStream(destFile);
imgWrier.reset();
// 必须先指定 out值,才能调用write方法, ImageOutputStream可以通过任何
// OutputStream构造
imgWrier.setOutput(ImageIO.createImageOutputStream(out));
// 调用write方法,就可以向输入流写图片
imgWrier.write(null, new IIOImage(src, null, null), imgWriteParams);
out.flush();
out.close();
return destFile;
}
}
/**
* 判断文件是否存在
* <p>Title: isBlank</p>
* <p>Description: </p>
* @param string
* @return
* @author yuh
*/
public static boolean isBlank(String string) {
if (string == null || string.length() == 0 || string.trim().equals("")) {
return true;
}
return false;
}
public static boolean isimg(File file) {
try {
Image image = ImageIO.read(file);
return image != null;
} catch (Exception ex) {
return false;
}
}
/**
* 使用ImageIO.read(file);压缩后的图片会变红改为使用
* Toolkit.getDefaultToolkit().getImage
* <p>Title: BufferedImageBuilder</p>
* <p>Description: </p>
* <p>Company: DXX</p>
* @author yuh
* @date 2019年6月4日
*/
public static class BufferedImageBuilder {
public static BufferedImage toBufferedImage(Image image) {
if (image instanceof BufferedImage) {
return (BufferedImage) image;
}
// This code ensures that all the pixels in the image are loaded
image = new ImageIcon(image).getImage();
BufferedImage bimage = null;
GraphicsEnvironment ge = GraphicsEnvironment
.getLocalGraphicsEnvironment();
try {
int transparency = Transparency.OPAQUE;
GraphicsDevice gs = ge.getDefaultScreenDevice();
GraphicsConfiguration gc = gs.getDefaultConfiguration();
bimage = gc.createCompatibleImage(image.getWidth(null),
image.getHeight(null), transparency);
} catch (HeadlessException e) {
// The system does not have a screen
}
if (bimage == null) {
// Create a buffered image using the default color model
int type = BufferedImage.TYPE_INT_RGB;
bimage = new BufferedImage(image.getWidth(null),
image.getHeight(null), type);
}
// Copy image to buffered image
Graphics g = bimage.createGraphics();
// Paint the image onto the buffered image
g.drawImage(image, 0, 0, null);
g.dispose();
return bimage;
}
}
}
2使用
只需要给定一个文件目录就可以将里面所有图片压缩成比较的小,而且不会怎么失真。放大也挺清楚的。
- 在服务器上,由于我没有配环境变量我是直接放在java的bin目录下,shift+鼠标右键选择在此处打开命令窗口,
- javac 文件名.java
- java 文件名
3说明
- 处理后的压缩图片名称=原图名称+_small
例如:test5.jpg 压缩后名称 test5_small.jpg - 压缩的图片后缀不会变。
- 压缩后图片路径与原图片路径一致。
数据库字段
对于客户上传附件(包含图片)一般是不会删除的,附件表里会包含有
原图字段file_path,和缩略图字段small_file_path.
展示时可以先判断是否有缩略图如果有则展示缩略图,没有则展示原图。
原图也没有可以展示一个暂无图片的静态图片文件。
注:图片具体压缩过程是网上搜索所得。具体来源已不知。