JAVA上傳影象時影象處理的基本方法
阿新 • • 發佈:2019-01-04
一,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();
}
}
}