最近遇到自拍上传图片过大问题,很烦恼,所以自己写了一个压缩图片的工具类使用,自测效果很不错,可以压缩到KB以内,像素还可以分辨清晰

下面Java代码奉上:

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

如有更正,欢迎下方评论联系我,谢谢

压缩图片工具类,压缩100KB以内拿走直接用的更多相关文章

  1. Java图片工具类,完成图片的截取和任意缩放

    package com.common.util; import java.awt.Graphics2D; import java.awt.Image; import java.awt.Renderin ...

  2. 拍照、本地图片工具类(兼容至Android7.0)

    拍照.本地图片工具类:解决了4.4以上剪裁会提示"找不到文件"和6.0动态授予权限,及7.0报FileUriExposedException异常问题. package com.hb ...

  3. Android--很实用的图片工具类

    import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileNotFoundException; imp ...

  4. Android 调节图片工具类

    package com.base.changeimage; import android.graphics.Bitmap; import android.graphics.Canvas; import ...

  5. 图片压缩java工具类

    package com.net.util; import java.awt.Image; import java.awt.image.BufferedImage; import java.io.Fil ...

  6. Java操作zip压缩和解压缩文件工具类

    需要用到ant.jar(这里使用的是ant-1.6.5.jar) import java.io.File; import java.io.FileInputStream; import java.io ...

  7. PHP图片压缩类,高清无损直接用就ok啦

    这个不完全是我自己写的-_-!,但是好用呀 <?php /** * Created by PhpStorm. * Note:文件介绍 * User: Lynly * Date: 2018/11/ ...

  8. java中自己常用到的工具类-压缩解压zip文件

    package com.ricoh.rapp.ezcx.admintoolweb.util; import java.io.File; import java.io.FileInputStream; ...

  9. Android list加载图片工具类

    总体思路 Handler + looper + message 核心类 package com.base.imagechoose.util; import android.graphics.Bitma ...

随机推荐

  1. CentOS7 安装 Python3.6.5

    在centos7下安装python3.6.5 CentOS7编译安装python3.6.8报错zipimport.ZipImportError: can't decompress data; zlib ...

  2. 神经网络训练技巧:训练参数初始化、Drop out及Batch Normalization

    参数初始化: xavier初始化: https://blog.csdn.net/VictoriaW/article/details/73000632 条件:优秀的初始化应该使得各层的激活值和梯度的方差 ...

  3. 安装后jdk1.8 配置环境变量以后 版本显示还是1.7

    配置图如下   1.7版本不用卸载  不用就可以了

  4. Python 基本数据类型详解

    1.数字 int(整型) 在32位机器上,整数的位数为32位,取值范围为-2**31-2**31-1,即-2147483648-2147483647在64位系统上,整数的位数为64位,取值范围为-2* ...

  5. VS2015开发常用快捷键

    以下内容均Ctrl+后面的按钮 M-O\P折叠 K-F 格式化 K-U\C注释 K-S侧外代码-(区域代码) 代码片段 ctor 自动生成默认的构造函数 prop 自动生成get set方法 cw 自 ...

  6. Ldap 从入门到放弃(一)

    OpenLDAP 2.4版本 快速入门 本文内容是自己通过官网文档.网络和相关书籍学习和理解并整理成文档,其中有错误或者疑问请在文章下方留言. 一.Introduction to OpenLDAP D ...

  7. LeetCode--062--不同路径(python)

    一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” ). 机器人每次只能向下或者向右移动一步.机器人试图达到网格的右下角(在下图中标记为“Finish”). 问总共有多 ...

  8. 02-webpack的作用

    webpack的作用,将不同静态资源的类型打包成一个JS文件,在html页面应用该JS文件的时候,JS文件里的html就可以正常的运行,去执行操作. 也可以加载前端页面的CSS样式.Img图片

  9. Socket网络通信编程(一)

    1.学习基本概念.传统的同步阻塞式I/O编程.伪异步IO实现 2.学习基于NIO的同步非阻塞式编程 3.了解基于NIO2.0的异步非阻塞(AIO)编程 1.1 基本概念 Socket又称“套接字”,应 ...

  10. 3D Computer Grapihcs Using OpenGL - 12 Rotation Matrix

    为了证明我们上节渲染出来的是一个立方体而不是一个平面,我们决定将它旋转一定角度,这样我们就需要一个旋转矩阵(也属于ModelTransformMatrix的一部分) 上一节我们的ModelTransf ...