Browse Source

图片压缩处理

chunping 3 years ago
parent
commit
34efbafa83

+ 93 - 13
mp-admin/src/main/java/com/qs/mp/web/controller/common/FileUploadController.java

@@ -13,7 +13,12 @@ import com.qs.mp.core.domain.LoginUser;
 import com.qs.mp.core.domain.UploadAttachment;
 import com.qs.mp.framework.security.handle.HostHolder;
 import java.awt.image.BufferedImage;
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
 import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
 import javax.imageio.ImageIO;
 import net.coobird.thumbnailator.Thumbnails;
 import net.coobird.thumbnailator.Thumbnails.Builder;
@@ -59,6 +64,16 @@ public class FileUploadController extends BaseApiController {
     @Autowired
     protected HostHolder hostHolder;
 
+    private static final Integer ZERO = 0;
+    private static final Integer ONE_ZERO_TWO_FOUR = 1024;
+    private static final Integer NINE_ZERO_ZERO = 900;
+    private static final Integer THREE_TWO_SEVEN_FIVE = 3275;
+    private static final Integer TWO_ZERO_FOUR_SEVEN = 2047;
+    private static final Double ZERO_EIGHT_FIVE = 0.85;
+    private static final Double ZERO_SIX = 0.6;
+    private static final Double ZERO_FOUR_FOUR = 0.44;
+    private static final Double ZERO_FOUR = 0.4;
+
     /**
      * 文件上传
      * @param fileType 文件类型
@@ -238,44 +253,109 @@ public class FileUploadController extends BaseApiController {
             suffix = fileName.substring(idx);
         }
         String name = UUIDUtils.newId() + suffix;
+        ByteArrayInputStream inputStream = null;
         try {
             QcloudFileUtils.putStream(file.getInputStream(), name, bucketName, mimeType );
-            BufferedImage bufferedImage = ImageIO.read(file.getInputStream());
+            /*BufferedImage bufferedImage = ImageIO.read(file.getInputStream());
             Builder<BufferedImage> builder = Thumbnails.of(bufferedImage);
 
 
             int pWidth = bufferedImage.getWidth();
             int pHeight = bufferedImage.getHeight();
+
             builder.size(pWidth, pHeight);
 
             String outFileDir = filePath+"/thumb";
             File tempFile = new File(outFileDir);
             if(!tempFile.exists()) {
                 tempFile.mkdirs();
-            }
+            }*/
             String thumbName = name +"_s";
-            String outFilePath = filePath+"/thumb/"+thumbName+"."+mimeType.substring(mimeType.lastIndexOf("/")+1);
-            builder.toFile(outFilePath);
+//            String outFilePath = filePath+"/thumb/"+thumbName+"."+mimeType.substring(mimeType.lastIndexOf("/")+1);
+//            builder.toFile(outFilePath);
 
             // 压缩图片
-            if (pWidth > 500) {
+            /*if (pWidth > 500) {
                 float scale = 500f / pWidth;
                 Thumbnails.of(outFilePath).scale(scale).outputQuality(0.8f).toFile(outFilePath);
             }else {
                 Thumbnails.of(outFilePath).scale(1f).outputQuality(0.8f).toFile(outFilePath);
-            }
-
+            }*/
+            byte[] outputBytes = compressPicForScale(file.getBytes(), file.getSize() * ONE_ZERO_TWO_FOUR);
+            inputStream = new ByteArrayInputStream(outputBytes);
+            QcloudFileUtils.putStream(inputStream, thumbName, bucketName, mimeType);
 
-            File outFile = new File(outFilePath);
-            QcloudFileUtils.putFile(outFile, thumbName, bucketName, mimeType);
-            if(outFile.exists()) {
-                LogUtil.info(log, "delete file..."+outFilePath);
-                outFile.delete();
-            }
         }  catch (Exception e) {
             LogUtil.error(log, e, "");
             return null;
+        } finally{
+            if (inputStream != null){
+                try{
+                    inputStream.close();
+                }catch (IOException e){
+                    LogUtil.error(log, e, "");
+                }
+            }
         }
         return name;
     }
+
+    /**
+     * 根据指定大小压缩图片
+     *
+     * @param imageBytes  源图片字节数组
+     * @param desFileSize 指定图片大小,单位kb
+     * @return 压缩质量后的图片字节数组
+     */
+    public static byte[] compressPicForScale(byte[] imageBytes, long desFileSize) {
+        if (imageBytes == null || imageBytes.length <= ZERO || imageBytes.length < desFileSize * ONE_ZERO_TWO_FOUR) {
+            return imageBytes;
+        }
+        long srcSize = imageBytes.length;
+        double accuracy = getAccuracy(srcSize / ONE_ZERO_TWO_FOUR);
+        try {
+
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream(imageBytes.length);
+            while (imageBytes.length > desFileSize * ONE_ZERO_TWO_FOUR) {
+                ByteArrayInputStream inputStream = null;
+                try {
+                 inputStream = new ByteArrayInputStream(imageBytes);
+                    Thumbnails.of(inputStream)
+                        .scale(accuracy)
+                        .outputQuality(accuracy)
+                        .toOutputStream(outputStream);
+                    imageBytes = outputStream.toByteArray();
+                } finally {
+                    if (null != inputStream) {
+                        inputStream.close();
+                    }
+                }
+            }
+            LogUtil.info(log, "图片原大小={}kb | 压缩后大小={}kb",
+                srcSize / ONE_ZERO_TWO_FOUR, imageBytes.length / ONE_ZERO_TWO_FOUR);
+        } catch (Exception e) {
+            LogUtil.error(log, "【图片压缩】msg=图片压缩失败!", e);
+        }
+        return imageBytes;
+    }
+
+    /**
+     * 自动调节精度(经验数值)
+     *
+     * @param size 源图片大小
+     * @return 图片压缩质量比
+     */
+    private static double getAccuracy(long size) {
+        double accuracy;
+        if (size < NINE_ZERO_ZERO) {
+            accuracy = ZERO_EIGHT_FIVE;
+        } else if (size < TWO_ZERO_FOUR_SEVEN) {
+            accuracy = ZERO_SIX;
+        } else if (size < THREE_TWO_SEVEN_FIVE) {
+            accuracy = ZERO_FOUR_FOUR;
+        } else {
+            accuracy = ZERO_FOUR;
+        }
+        return accuracy;
+    }
 }