最近的業(yè)務(wù)里有一個(gè)場(chǎng)景:需要通過(guò)接口傳遞圖片的base64字符串實(shí)現(xiàn)圖片的上傳功能,但眾所周知,即使是post請(qǐng)求,也對(duì)報(bào)文的大小有所限制,而圖片的base64字符串有多長(zhǎng)呢,如果不是很清楚的話,可以打印出來(lái)看一下。
因此,需要將圖片進(jìn)行壓縮,使大小控制在可行的范圍內(nèi),再轉(zhuǎn)成base64字符串,通過(guò)接口進(jìn)行傳輸。
具體實(shí)現(xiàn)代碼如下:
@Slf4j
public class ImageUtilJnb {
private static int mb = 1048576;// 1MB
public static void main(String[] args) {
String fullPath="D:\\123.jpg";
String newPath="D:\\321322198511205873F.jpg";
long length = new File(fullPath).length();
if (length / 1048576 >= JnbConstants.JNB_IMAGE_RATE) {// 如果圖片大于等于0.5MB 則按80%縮小
try {
ImageUtilJnb.zoom(fullPath, newPath, length, JnbConstants.JNB_IMAGE_RATE);
} catch (IOException e) {
log.error("出錯(cuò)啦:" + e);
}
}
String base64Str = Base64Util.getBase64Str(newPath);
System.out.println("base64Str===" + base64Str);
}
// 縮圖
public static void zoom(String oldFile, String zoomFile,long length,double newRate) throws IOException {
DecimalFormat df = new DecimalFormat("0.00");// 設(shè)置保留位數(shù)
double rate=0.8;
log.info("原始圖片大?。? + df.format((float) length / mb) + "MB");
long newfile = new File(oldFile).length();
int i = 1;
// 如果首次壓縮還大于2MB則繼續(xù)處理
while ((float) newfile / mb >= newRate) {
log.info("壓縮后圖片大小:" + newfile);
rate = rate - 0.05;// 暫定按照0.03頻率壓縮
log.info(i + " rate=" + rate);
BufferedImage srcImage = ImageIO.read(new File(oldFile));
int WIDTH = (int) (srcImage.getWidth() * rate);
int HEIGHT = (int) (srcImage.getHeight() * rate);
BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
Graphics g = image.getGraphics();
g.drawImage(srcImage, 0, 0, WIDTH, HEIGHT, null);
// 縮小
ImageIO.write(image, "jpg", new File(zoomFile));
i++;
newfile = new File(zoomFile).length();
log.info("壓縮次數(shù):" + i);
}
// 調(diào)整方向
BufferedImage newImage = ImageIO.read(new File(zoomFile));
BufferedImage image1 = Rotate(newImage, 90);// 順時(shí)針旋轉(zhuǎn)90度
ImageIO.write(image1, "jpg", new File(zoomFile));
log.info("處理后圖片路徑:" + zoomFile + ";縮小之后大?。?
+ df.format((float) new File(zoomFile).length() / mb) + "MB");
}
/**
* 對(duì)圖片進(jìn)行旋轉(zhuǎn)
*
* @param src
* 被旋轉(zhuǎn)圖片
* @param angel
* 旋轉(zhuǎn)角度
* @return 旋轉(zhuǎn)后的圖片
*/
public static BufferedImage Rotate(Image src, int angel) {
int src_width = src.getWidth(null);
int src_height = src.getHeight(null);
// 計(jì)算旋轉(zhuǎn)后圖片的尺寸
Rectangle rect_des = CalcRotatedSize(new Rectangle(new Dimension(src_width, src_height)), angel);
BufferedImage res = null;
res = new BufferedImage(rect_des.width, rect_des.height, BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = res.createGraphics();
// 進(jìn)行轉(zhuǎn)換
g2.translate((rect_des.width - src_width) / 2, (rect_des.height - src_height) / 2);
g2.rotate(Math.toRadians(angel), src_width / 2, src_height / 2);
g2.drawImage(src, null, null);
return res;
}
/**
* 計(jì)算旋轉(zhuǎn)后的圖片
*
* @param src
* 被旋轉(zhuǎn)的圖片
* @param angel
* 旋轉(zhuǎn)角度
* @return 旋轉(zhuǎn)后的圖片
*/
public static Rectangle CalcRotatedSize(Rectangle src, int angel) {
// 如果旋轉(zhuǎn)的角度大于90度做相應(yīng)的轉(zhuǎn)換
if (angel >= 90) {
if (angel / 90 % 2 == 1) {
int temp = src.height;
src.height = src.width;
src.width = temp;
}
angel = angel % 90;
}
double r = Math.sqrt(src.height * src.height + src.width * src.width) / 2;
double len = 2 * Math.sin(Math.toRadians(angel) / 2) * r;
double angel_alpha = (Math.PI - Math.toRadians(angel)) / 2;
double angel_dalta_width = Math.atan((double) src.height / src.width);
double angel_dalta_height = Math.atan((double) src.width / src.height);
int len_dalta_width = (int) (len * Math.cos(Math.PI - angel_alpha - angel_dalta_width));
int len_dalta_height = (int) (len * Math.cos(Math.PI - angel_alpha - angel_dalta_height));
int des_width = src.width + len_dalta_width * 2;
int des_height = src.height + len_dalta_height * 2;
return new Rectangle(new Dimension(des_width, des_height));
}
}