一,form表單類型
<form id="xxForm" action="xx.htm" method="post" enctype ="multipart/form-data" >
則請求頭含有:
formdata
-----------------------------14471729621574
Content-Disposition: form-data; name="Filedata"; filename="11.jpg"
Content-Type:
image/jpeg
二,文件大小控制(3M)
MultipartFile file = ((MultipartHttpServletRequest) request).getFile("Filedata");
if (file == null || file.getSize() >= 3 * 1024 * 1024) {
showErrorMsg();
}
三,文件後綴名控制
直接使用MultipartFile file 的getOriginalFilename()方法,獲取到的中文名稱可能是亂碼。建議單獨傳參fileName
String suffix = StringUtil.substringAfterLast(fileName, ".").toLowerCase();
if (!suffix.matches(IMAGE_TYPE)) {
showErrorMsg();
}
private static final String IMAGE_TYPE = "(jpg|jpeg|png)";
四,文件安全檢查
以上三種類型都應該可以正常轉換爲jpg文件
try {
src = ImageIO.read(infile.getInputStream());
} catch (IOException e) {
throw e;
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(src, "jpg", baos);
五,圖片裁剪,縮放
/**
* 裁剪圖片
*
* @param in
* @param out
* @param format (jpg,jpeg,png)
* @param x 截取後的x座標
* @param y 截取後的y座標
* @param width 截取後的寬度
* @param height 截取後的高度
* @param orgWidth 圖片寬度
* @param orgHeight 圖片高度
*/
public static void clipPic(ByteArrayInputStream in, ByteArrayOutputStream out, String format,
int x, int y, int width, int height, int orgWidth, int orgHeight) {
try {
LoggerUtil.info(LOGGER, "[PicCompress]開始裁減圖片! ");
BufferedImage tag = ImageIO.read(in);
BufferedImage oute = null;
int sourceWidth = tag.getWidth();
int sourceHeight = tag.getHeight();
if (width >= orgWidth && height >= orgHeight) {
oute = tag.getSubimage(0, 0, sourceWidth, sourceHeight);
} else {
double rateW = (double) sourceWidth / (double) orgWidth;
double rateH = (double) sourceHeight / (double) orgHeight;
int targetWidth = (int) ((width < orgWidth ? width : orgWidth) * rateW);
int targetHeight = (int) ((height < orgHeight ? height : orgHeight) * rateH);
int targetX = (int) (x * rateW);
int targetY = (int) (y * rateH);
oute = tag.getSubimage(targetX, targetY, targetWidth, targetHeight);
}
//保存新圖片
ImageIO.write(oute, format, out);
} catch (IOException e) {
LoggerUtil.warn(LOGGER, "[PicCompress]裁減圖片失敗! ", e);
}
}
六,圖片壓縮
public static void compressPic(ByteArrayInputStream in, ByteArrayOutputStream out,
String format, int size, int limitSize) {
try {
BufferedImage img = ImageIO.read(in);
double rate = (double) limitSize / (double) size;
int width = (int) (img.getWidth() * rate);
int height = (int) (img.getHeight() * rate);
BufferedImage tag = null;
if (StringUtil.equals(format, "png")) {
tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
} else {
tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
}
tag.getGraphics().drawImage(img.getScaledInstance(width, height, Image.SCALE_SMOOTH),
0, 0, null);
//保存新圖片
ImageIO.write(tag, format, out);
} catch (IOException e) {
LoggerUtil.warn(LOGGER, "[PicCompress]壓縮圖片大小失敗! ", e);
}
}
七,其他流處理工具
轉換
/**
* 從輸入流讀取內容, 寫入到輸出流中. 使用指定大小的緩衝區.
*
* @param in 輸入流
* @param out 輸出流
* @param bufferSize 緩衝區大小(字節數)
*
* @throws IOException 輸入輸出異常
*/
public static void io(InputStream in, OutputStream out, int bufferSize)
throws IOException {
if (bufferSize == -1) {
bufferSize = DEFAULT_BUFFER_SIZE;
}
byte[] buffer = new byte[bufferSize];
int amount;
while ((amount = in.read(buffer)) >= 0) {
out.write(buffer, 0, amount);
}
}
private static final int DEFAULT_BUFFER_SIZE = 8192;
關閉,應當在finally中執行
/**
* 安全的關閉流
* @param <T>
* @param stream
*/
public static <T extends Closeable> void closeStreamSafely(T stream) {
if (stream == null) {
return;
}
try {
stream.close();
} catch (IOException e) {
//ignore
}
}
同步化的輸出流
/**
* 同步化的輸出流包裹器.
*/
private static class SynchronizedOutputStream extends OutputStream {
private OutputStream out;
private Object lock;
SynchronizedOutputStream(OutputStream out) {
this(out, out);
}
SynchronizedOutputStream(OutputStream out, Object lock) {
this.out = out;
this.lock = lock;
}
public void write(int datum) throws IOException {
synchronized (lock) {
out.write(datum);
}
}
public void write(byte[] data) throws IOException {
synchronized (lock) {
out.write(data);
}
}
public void write(byte[] data, int offset, int length)
throws IOException {
synchronized (lock) {
out.write(data, offset, length);
}
}
public void flush() throws IOException {
synchronized (lock) {
out.flush();
}
}
public void close() throws IOException {
synchronized (lock) {
out.close();
}
}
}