Java 处理图片-压缩本地图片及远程图片,按照BASE64格式输出
很久没有写博客了,不是我颓废了,而是实在是太忙了,抽不出时间也抽不出经历写东西了,幸亏项目已经落地,没有那么的忙了,记录一下。
最近在做导出,发现很多时候导出的图片太大了,及其容易引起堆栈溢出,图片必须经过压缩再导出了,由于客户对图片质量要求不是特别高,能看清即可,所以直接等比例压缩即可,尽量保证质量不变,只改变其大小,废话不多说,整起
-
第一层入口,由于我们的图片信息是存放再json字段中的,为了避免转换时出现双引号,所以判断就或一下啦。方法支持base64压缩以及远程图片压缩两种方式,实际判断可以根据需求进行修改
/** * 根据传递的参数来处理图片,不是图片时直接返回null * * @param str 图片info * @return 压缩后的图片 */ public static String strToImageBase64(String str) { if (StringUtils.hasLength(str) && (str.startsWith("data:image/png;base64,") || str.startsWith("\"data:image/png;base64,"))) { //去掉base64的头部信息 String autonomyDeclareSign = str.replace("\"data:image/png;base64,", "").replace("\"", ""); //压缩图片大小 String autonomyDeclareSignPng = ImageUtils.scaleImage(autonomyDeclareSign, "png"); return ObjectUtils.isEmpty(autonomyDeclareSignPng) || autonomyDeclareSignPng.equals("0") ? null : autonomyDeclareSignPng; } else { //不是base64时,直接按照远程url获取图片并压缩 String autonomyDeclareSignPng = ImageUtils.imageToBase64(str, "png"); return ObjectUtils.isEmpty(autonomyDeclareSignPng) || autonomyDeclareSignPng.equals("0") ? null : autonomyDeclareSignPng; } }
2.BASE64图片压缩方法
/** * 根据图片的base64数据缩放图片20kb * * @param base64ImagStr 原图的base64字符换 * @param imageType 图片类型 * @return base64数据缩放图片 */ public static String scaleImage(String base64ImagStr, String imageType) { if (StringUtils.hasLength(base64ImagStr) && !"0".equals(base64ImagStr)) { BufferedImage bufferedImage; try { //获取图片的buffer bufferedImage = ImgUtil.toImage(base64ImagStr); } catch (Exception e) { return null; } //获取图片的宽度 int width = bufferedImage.getWidth(); //获取图片的高度 int height = bufferedImage.getHeight(); //计算图片需要压缩的比例,宽高相等时,在原比例直接除以2 if (width == height) { width = width / 2; height = height / 2; //宽大于高,先计算出宽高相差倍数,然后宽/2,高度=宽/原比例 } else if (width > height) { double v = width / (height * 1.000000); width = width / 2; height = (int) (width / v); } else { //高大于宽,先计算出宽高相差倍数,然后高/2,宽度=高/原比例 double v = width / (height * 1.000000); height = height / 2; width = (int) (height / v); } // 通过计算出的宽高来压缩图片,此时只压缩图片的大小,不压缩质量 //质量:等比例质量,即原1024*1024 压缩后 512*512 Image scaleImage = ImgUtil.scale(bufferedImage, width, height); //根据图片类型,转化图片为base64 String resultBase64Str = ImgUtil.toBase64(scaleImage, imageType); //计算图片大小 Integer imageSizeBase64 = imageSize(resultBase64Str); //如果图片大于20KB,继续压缩 if (imageSizeBase64 > 20) { resultBase64Str = scaleImage(resultBase64Str, imageType); } return resultBase64Str; } return base64ImagStr; }
/** * 计算图片的大小,返回单位为KB * * @param imageBase64Str 图片base64数据 * @return 图片大小 */ public static Integer imageSize(String imageBase64Str) { //1.找到等号,把等号也去掉(=用来填充base64字符串长度用) int equalIndex = imageBase64Str.indexOf("="); if (imageBase64Str.indexOf("=") > 0) { imageBase64Str = imageBase64Str.substring(0, equalIndex); } //2.原来的字符流大小,单位为字节 int strLength = imageBase64Str.length(); System.out.println("imageBase64Str Length = " + strLength); //3.计算后得到的文件流大小,单位为字节 int size = strLength - (strLength / 8) * 2; return bytesToKB(size); }
/** * byte(字节)根据长度转成kb(千字节) * * @param bytes 字节 * @return 大小 */ public static Integer bytesToKB(long bytes) { BigDecimal filesize = new BigDecimal(bytes); BigDecimal kilobyte = new BigDecimal(1024); float returnValue = filesize.divide(kilobyte, 1, RoundingMode.DOWN).floatValue(); return (int) returnValue; }
3.远程图片压缩(其中会调用BASE64压缩)
/** * 通过图片的url获取图片的base64字符串,同时压缩图片 * * @param imgUrl 图片url * @param suffix 图片后缀 * @return 返回图片base64的字符串 */ public static String imageToBase64(String imgUrl, String suffix) { if (ObjectUtils.isEmpty(imgUrl) || "null".equals(imgUrl)) { return null; } URL url; InputStream is = null; ByteArrayOutputStream outStream = null; HttpURLConnection httpUrl = null; try { url = new URL(imgUrl); httpUrl = (HttpURLConnection) url.openConnection(); httpUrl.connect(); is = httpUrl.getInputStream(); outStream = new ByteArrayOutputStream(); //创建一个Buffer字符串 byte[] buffer = new byte[1024]; //每次读取的字符串长度,如果为-1,代表全部读取完毕 int len; //使用一个输入流从buffer里把数据读取出来 while ((len = is.read(buffer)) != -1) { //用输出流往buffer里写入数据,中间参数代表从哪个位置开始读,len代表读取的长度 outStream.write(buffer, 0, len); } // 对字节数组Base64编码 Base64.Encoder base64Encoder = Base64.getEncoder(); String encodeToString = base64Encoder.encodeToString(outStream.toByteArray()); return scaleImage(encodeToString, suffix); } catch (Exception e) { System.out.println("图片解析失败" + imgUrl); } finally { if (is != null) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } if (outStream != null) { try { outStream.close(); } catch (IOException e) { e.printStackTrace(); } } if (httpUrl != null) { httpUrl.disconnect(); } } return null; }