壓縮圖片工具類,壓縮100KB之內拿走直接用

最近遇到自拍上傳圖片過大問題,很煩惱,因此本身寫了一個壓縮圖片的工具類使用,自測效果很不錯,能夠壓縮到KB之內,像素還能夠分辨清晰java

下面Java代碼奉上:ios

 

  1 import lombok.extern.slf4j.Slf4j;
  2 import org.w3c.dom.Element;
  3 
  4 
  5 import javax.imageio.IIOImage;
  6 import javax.imageio.ImageIO;
  7 import javax.imageio.ImageTypeSpecifier;
  8 import javax.imageio.ImageWriter;
  9 import javax.imageio.metadata.IIOMetadata;
 10 import javax.imageio.plugins.jpeg.JPEGImageWriteParam;
 11 import javax.imageio.stream.ImageOutputStream;
 12 import java.awt.*;
 13 import java.awt.image.BufferedImage;
 14 import java.io.*;
 15 import java.net.HttpURLConnection;
 16 import java.net.URL;
 17 
 18 
 19 /**
 20  * @Author: Mr. Chang
 21  */
 22 @Slf4j
 23 public class ImageZipUtils {
 24 
 25     /**
 26      * 採用指定寬度、高度或壓縮比例 的方式對圖片進行壓縮
 27      *
 28      * @param imgsrc     源圖片地址
 29      * @param imgdist    目標圖片地址
 30      * @param widthdist  壓縮後圖片寬度(當rate==null時,必傳)
 31      * @param heightdist 壓縮後圖片高度(當rate==null時,必傳)
 32      * @param rate       壓縮比例
 33      */
 34     public static void reduceImg(String imgsrc, String imgdist, int widthdist,
 35                                  int heightdist, Float rate) {
 36         try {
 37             File srcfile = new File(imgsrc);
 38             // 檢查文件是否存在
 39             if (!srcfile.exists()) {
 40                 return;
 41             }
 42             // 若是rate不爲空說明是按比例壓縮
 43             if (rate != null && rate > 0) {
 44                 // 獲取文件高度和寬度
 45                 int[] results = getImgWidth(srcfile);
 46                 if (results == null || results[0] == 0 || results[1] == 0) {
 47                     return;
 48                 } else {
 49                     widthdist = (int) (results[0] * rate);
 50                     heightdist = (int) (results[1] * rate);
 51                 }
 52             }
 53             // 開始讀取文件並進行壓縮
 54             Image src = javax.imageio.ImageIO.read(srcfile);
 55             BufferedImage tag = new BufferedImage((int) widthdist,
 56                     (int) heightdist, BufferedImage.TYPE_INT_RGB);
 57 
 58             tag.getGraphics().drawImage(
 59                     src.getScaledInstance(widthdist, heightdist,
 60                             Image.SCALE_SMOOTH), 0, 0, null);
 61 
 62             FileOutputStream out = new FileOutputStream(imgdist);
 63 //            JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
 64 //            encoder.encode(tag);
 65 //            out.close();
 66             float per = (float) 0.85;
 67             saveAsJPEG(100, tag, per, out);
 68 
 69         } catch (IOException ex) {
 70             ex.printStackTrace();
 71         }
 72     }
 73 
 74     /**
 75      * 以JPEG編碼保存圖片
 76      *
 77      * @param dpi             分辨率
 78      * @param image_to_save   要處理的圖像圖片
 79      * @param JPEGcompression 壓縮比
 80      * @param fos             文件輸出流
 81      * @throws IOException
 82      */
 83     public static void saveAsJPEG(Integer dpi, BufferedImage image_to_save, float JPEGcompression, FileOutputStream fos) throws IOException {
 84         // Image writer
 85         ImageWriter imageWriter = ImageIO.getImageWritersBySuffix("jpg").next();
 86         ImageOutputStream ios = ImageIO.createImageOutputStream(fos);
 87         imageWriter.setOutput(ios);
 88         //and metadata
 89         IIOMetadata imageMetaData = imageWriter.getDefaultImageMetadata(new ImageTypeSpecifier(image_to_save), null);
 90 
 91 
 92         if (dpi != null && !dpi.equals("")) {
 93 
 94             //new metadata
 95             Element tree = (Element) imageMetaData.getAsTree("javax_imageio_jpeg_image_1.0");
 96             Element jfif = (Element) tree.getElementsByTagName("app0JFIF").item(0);
 97             jfif.setAttribute("Xdensity", Integer.toString(dpi));
 98             jfif.setAttribute("Ydensity", Integer.toString(dpi));
 99 
100         }
101 
102 
103         if (JPEGcompression >= 0 && JPEGcompression <= 1f) {
104             // new Compression
105             JPEGImageWriteParam jpegParams = (JPEGImageWriteParam) imageWriter.getDefaultWriteParam();
106             jpegParams.setCompressionMode(JPEGImageWriteParam.MODE_EXPLICIT);
107             jpegParams.setCompressionQuality(JPEGcompression);
108 
109         }
110 
111         //new Write and clean up
112         imageWriter.write(imageMetaData, new IIOImage(image_to_save, null, null), null);
113         ios.close();
114         imageWriter.dispose();
115 
116     }
117 
118 
119     /**
120      * 獲取圖片寬度
121      *
122      * @param file 圖片文件
123      * @return 寬度
124      */
125     public static int[] getImgWidth(File file) {
126         InputStream is = null;
127         BufferedImage src = null;
128         int result[] = {0, 0};
129         try {
130             is = new FileInputStream(file);
131             src = javax.imageio.ImageIO.read(is);
132             result[0] = src.getWidth(null); // 獲得源圖寬
133             result[1] = src.getHeight(null); // 獲得源圖高
134             is.close();
135         } catch (Exception e) {
136             e.printStackTrace();
137         }
138         return result;
139     }
140 
141     public static byte[] readInputStream(InputStream inStream) throws Exception {
142         ByteArrayOutputStream outStream = new ByteArrayOutputStream();
143         //建立一個Buffer字符串
144         byte[] buffer = new byte[1024];
145         //每次讀取的字符串長度,若是爲-1,表明所有讀取完畢
146         int len = 0;
147         //使用一個輸入流從buffer裏把數據讀取出來
148         while ((len = inStream.read(buffer)) != -1) {
149             //用輸出流往buffer裏寫入數據,中間參數表明從哪一個位置開始讀,len表明讀取的長度
150             outStream.write(buffer, 0, len);
151         }
152         //關閉輸入流
153         inStream.close();
154         //把outStream裏的數據寫入內存
155         return outStream.toByteArray();
156     }
157 
158     /**
159      * 保存自拍照片
160      * @param userId
161      * @param photo_url
162      * @param suffixFromUrl
163      * @param path
164      * @throws Exception
165      */
166     public static void saveZipImage(Integer userId, String photo_url, String suffixFromUrl, String path) throws Exception {
167 
168         //new一個URL對象
169         URL url = new URL(photo_url);
170         //打開連接
171         HttpURLConnection conn = (HttpURLConnection) url.openConnection();
172         //設置請求方式爲"GET"
173         conn.setRequestMethod("GET");
174         //超時響應時間爲5秒
175         conn.setConnectTimeout(5 * 1000);
176         //經過輸入流獲取圖片數據
177         InputStream inStream = conn.getInputStream();
178         //獲得圖片的二進制數據,以二進制封裝獲得數據,具備通用性
179         byte[] data = readInputStream(inStream);
180         //new一個文件對象用來保存圖片,默認保存當前工程根目錄
181         File imageFile = new File(path + userId + suffixFromUrl);
182         //建立輸出流
183         FileOutputStream outStream = new FileOutputStream(imageFile);
184         //寫入數據
185         outStream.write(data);
186         //關閉輸出流
187         outStream.close();
188 
189     }
190 
191     /**
192      * 開始壓縮圖片
193      * @param userId
194      * @param suffix
195      * @param path
196      * @return
197      */
198     public static String imageZipStart(Integer userId, String suffix, String path) {
199         /**
200          * d://3.jpg 源圖片
201          * d://31.jpg 目標圖片
202          * 壓縮寬度和高度都是1000
203          *
204          */
205         String original = path + userId + suffix;
206         String target = path + userId + "target" + suffix;
207         File srcfile = new File(original);
208         log.info(userId + "用戶自拍照壓縮前自拍照大小:" + srcfile.length());
209         reduceImg(original, target, 888, 888, null);
210         File distfile = new File(target);
211         log.info("用戶自拍照壓縮後自拍照大小:" + distfile.length());
212         return target;
213     }
214 
215     /**
216      * 刪除文件
217      */
218     public static void delFile(String fileName) {
219         File deFile = new File(fileName);
220         if (deFile.exists()) {
221             deFile.delete();
222         }
223     }
224 
225 }

 

若有更正,歡迎下方評論聯繫我,謝謝app

相關文章
相關標籤/搜索