获取普通图片和svg图片属性,并实现单张下载和批量下载,svg转png下载,图片大小压缩
2020-08-31 12:25
232 查看
1. 获取图片属性(分辨率,大小,颜色模式,后缀名)
@Override public PictureAttributeVo saveUpload(MultipartFile file) throws Exception { if (file == null) { throw new Exception("文件有误"); } String filename = file.getOriginalFilename(); //图标大小,处理为b long size = file.getSize(); //根据后缀判断图标类型 String type = FilenameUtils.getExtension(file.getOriginalFilename()).toUpperCase(); BufferedImage read = ImageIO.read((FileInputStream) file.getInputStream()); //获取图片颜色模式,RGB,CMYK等,具体可点进去getType自己看 //这个网上找了好久没找到,应该可以解决一些人的问题 ColorModel colorModel = read.getColorModel(); int typeCode = colorModel.getColorSpace().getType(); String mode = ""; mode = PictureUtils.getColorModel(typeCode); if (!"JPG".equals(type) && !"PNG".equals(type) && !"GIF".equals(type) && !"TIF".equals(type) && !"BMP".equals(type) && !"JPEG".equals(type)) { throw new Exception("图片格式有误"); } //获取图片base64 byte[] bytes = file.getBytes(); String base = new String(Base64.encodeBase64(bytes)); String thumbnailPictureCode = new String(Base64.encodeBase64(bytes)); //获取图标宽高 BufferedImage sourceImg = ImageIO.read((FileInputStream) file.getInputStream()); int width = sourceImg.getWidth(); int height = sourceImg.getHeight(); //拼接出分辨率 String resolutionRatio = width + "x" + height + "px"; }
2. svg图片只有分辨率值得一说,而且也没有颜色模式
public static String getSvgWidthAndHeight(String svgURI) throws IOException { File file = new File(svgURI); String parser = XMLResourceDescriptor.getXMLParserClassName(); SAXSVGDocumentFactory f = new SAXSVGDocumentFactory(parser); Document doc = f.createDocument(file.toURI().toString()); Element element = doc.getDocumentElement(); String viewBox = element.getAttribute("viewBox"); String width = viewBox.split(" ")[2]; String height = viewBox.split(" ")[3]; //分辨率 String resolutionRatio = width+"x"+height+"px"; //这里只能先在服务器生成一个文件获取分辨率,所以要删除,图片可以用流读取 file.delete(); return resolutionRatio; }
3. 图片大小压缩
/** * 根据指定大小压缩图片 * * @param imageBytes 源图片字节数组 * @param fileSize 指定图片大小,单位kb * @return 压缩质量后的图片字节数组 */ public static byte[] compressPicture(byte[] imageBytes, long fileSize) { if (imageBytes == null || imageBytes.length <= 0 || imageBytes.length < fileSize * 1024) { return imageBytes; } long srcSize = imageBytes.length; double accuracy = getAccuracy(srcSize / 1024); try { while (imageBytes.length > fileSize * 1024) { ByteArrayInputStream inputStream = new ByteArrayInputStream(imageBytes); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(imageBytes.length); Thumbnails.of(inputStream) .scale(accuracy) .outputQuality(accuracy) .toOutputStream(outputStream); imageBytes = outputStream.toByteArray(); } } catch (Exception e) { logger.error("图片压缩失败", e); } return imageBytes; }
4. svg转png格式下载
因为前端有个功能是修改svg颜色,所以我需要先传给他svg代码,很简单,把svg图片导出成txt格式用流读取即可,让前端去掉字符串中的"\"这个转义字符.
这里svgcode是svg代码,是前端修改完svg图片颜色传回来的
@Override public void downloadPngIcon(HttpServletRequest request, HttpServletResponse response, SvgVo svgVo) throws Exception { Integer id = svgVo.getId(); String svgCode = svgVo.getSvgCode(); if (id == null || iconAttributeMapper.selectById(id) == null) { throw new Exception("图标不存在"); } //获取图标名和后缀 TUedIconAttribute tUedIconAttribute = iconAttributeMapper.selectById(id); //更新图标下载量 tUedIconAttribute.setDownloadCount(tUedIconAttribute.getDownloadCount() + 1); iconAttributeMapper.updateById(tUedIconAttribute); String imageName = tUedIconAttribute.getImageName(); Integer imageId = tUedIconAttribute.getImageId(); TUedPicture tUedPicture = pictureMapper.selectById(imageId); String pictureCode = tUedPicture.getPictureCode(); String format = tUedPicture.getFormat().toLowerCase(); String fileName = imageName + ".png"; String agent = request.getHeader("User-Agent").toUpperCase(); // 判断浏览器代理并分别设置响应给浏览器的编码格式 String finalFileName = null; if (agent.contains("MSIE") || ((agent.indexOf("RV") != -1) && (agent.indexOf("FIREFOX") == -1))) { finalFileName = URLEncoder.encode(fileName, "UTF-8"); } else { finalFileName = new String(fileName.getBytes("UTF-8"), "ISO8859-1"); } //设置响应 response.setContentType("application/x-download");// 告知浏览器下载文件,而不是直接打开,浏览器默认为打开 response.setHeader("Content-Disposition", "attachment;filename=\"" + finalFileName + "\"");// 下载文件的名称 BASE64Decoder decoder = new BASE64Decoder(); ServletOutputStream outputStream = response.getOutputStream(); //如果是svg图片下载成png图片 if ("svg".equals(format)) { try { String svgPicture = "D:\\" + UUID.randomUUID().toString() + ".svg"; if (svgCode != null) { FileOutputStream fos = null; try { byte[] svgCodeBytes = svgCode.getBytes(); fos = new FileOutputStream(new File(svgPicture)); fos.write(svgCodeBytes); } catch (IOException e) { throw new Exception(); } finally { fos.flush(); fos.close(); } String newSvgCode = PictureUtils.getImgStr(svgPicture); new File(svgPicture).delete(); byte[] bytes = decoder.decodeBuffer(newSvgCode); PNGTranscoder t = new PNGTranscoder(); TranscoderInput input = new TranscoderInput(new ByteArrayInputStream(bytes)); TranscoderOutput output = new TranscoderOutput(outputStream); t.transcode(input, output); outputStream.flush(); } } catch (Exception e) { throw new Exception(); } finally { if (outputStream != null) { try { outputStream.close(); } catch (IOException e) { log.info("下载图标失败",e); } } } } else if ("png".equals(format)) { try { // Base64解码 byte[] b = decoder.decodeBuffer(pictureCode); for (int i = 0; i < b.length; ++i) { if (b[i] < 0) {// 调整异常数据 b[i] += 256; } } outputStream.write(b); outputStream.flush(); } catch (Exception e) { throw new Exception(); } finally { if (outputStream != null) { try { outputStream.close(); } catch (IOException e) { log.info("下载图标失败",e); } } } } }
5. 单张图片下载
@Override public void pictureDownload(HttpServletRequest request, HttpServletResponse response, Integer id) throws Exception { // 得到要下载的文件名 TUedPictureAttribute tUedPictureAttribute = pictureAttributeMapper.selectById(id); //下载量加1 tUedPictureAttribute.setDownloadCount(tUedPictureAttribute.getDownloadCount() + 1); pictureAttributeMapper.updateById(tUedPictureAttribute); Integer imageId = tUedPictureAttribute.getImageId(); String imageName = tUedPictureAttribute.getImageName(); TUedPicture tUedPicture = pictureMapper.selectById(imageId); String pictureCode = tUedPicture.getPictureCode(); String format = tUedPicture.getFormat(); String fileName = imageName + "." + format.toLowerCase(); // 处理文件名 // 设置响应头,控制浏览器下载该文件 //解决中文文件名乱码 String userAgent = request.getHeader("User-Agent"); //IE内核浏览器 if (userAgent.contains("MSIE") || userAgent.contains("Trident")) { fileName = java.net.URLEncoder.encode(fileName, "UTF-8"); } else { // 非IE浏览器的处理: fileName = new String(fileName.getBytes("utf-8"), "iso-8859-1"); } //设置文件下载头 response.setHeader("Content-disposition", String.format("attachment; filename=\"%s\"", fileName)); //设置文件ContentType类型,这样设置,会自动判断下载文件类型 response.setContentType("multipart/form-data"); response.setCharacterEncoding("iso-8859-1"); // 读取要下载的文件,保存到文件输入流 BASE64Decoder decoder = new BASE64Decoder(); OutputStream out = response.getOutputStream(); try { // Base64解码 byte[] b = decoder.decodeBuffer(pictureCode); for (int i = 0; i < b.length; ++i) { if (b[i] < 0) {// 调整异常数据 b[i] += 256; } } out.write(b); } catch (Exception e) { throw new Exception(); }finally { out.close(); } }
6. 整套图标下载
@Override public void downloadAllIcon(HttpServletRequest request, HttpServletResponse response, Integer id) throws Exception { if (id == null || packageMapper.selectById(id) == null) { throw new Exception("图标库信息有误"); } TUedIconPackage tUedIconPackage = packageMapper.selectById(id); //更新图标库下载量 tUedIconPackage.setDownloadCount(tUedIconPackage.getDownloadCount() + 1); packageMapper.updateById(tUedIconPackage); String packageName = tUedIconPackage.getPackageName(); // path 压缩文件初始设置 String fileZip = packageName + ".zip"; // 拼接zip文件,之后下载下来的压缩文件的名字 String filePath = "D:\\" + fileZip;// 之后用来生成zip文件//data//ued1//image List<IconVo> iconVos = pictureMapper.selectIconsByPackageId(id, null); for (IconVo iconVo : iconVos) { Integer iconId = iconVo.getIconId(); TUedIconAttribute tUedIconAttribute = iconAttributeMapper.selectById(iconId); tUedIconAttribute.setDownloadCount(tUedIconAttribute.getDownloadCount() + 1); iconAttributeMapper.updateById(tUedIconAttribute); } //处理图标重名问题 ArrayList<String> list = new ArrayList<>(); HashSet<String> arrayList = new HashSet<>(); for (IconVo iconVo : iconVos) { list.add(iconVo.getIconName()); arrayList.add(iconVo.getIconName()); } for (String s : arrayList) { Integer count =0; for (int i = 0; i < list.size(); i++) { if (list.get(i).equals(s)){ count++; if (count!=1){ list.set(i,list.get(i)+"("+(count-1)+")"); } } } count =0; } for (int i = 0; i < iconVos.size(); i++) { IconVo iconVo = iconVos.get(i); iconVo.setIconName(list.get(i)); } // 创建临时压缩文件 BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(filePath)); ZipOutputStream zos = new ZipOutputStream(bos); try { ZipEntry ze = null; BASE64Decoder decoder = new BASE64Decoder(); for (int i = 0; i < iconVos.size(); i++) {// 将所有需要下载的文件都写入临时zip文件 // Base64解码 byte[] b = decoder.decodeBuffer(iconVos.get(i).getPictureCode()); for (int j = 0; j < b.length; ++j) { if (b[i] < 0) {// 调整异常数据 b[i] += 256; } } String iconName = iconVos.get(i).getIconName(); String format = iconVos.get(i).getFormat(); ze = new ZipEntry(iconName + "." + format.toLowerCase()); zos.putNextEntry(ze); zos.write(b); } } catch (IOException e) { throw new Exception("临时压缩文件生成失败"); }finally { zos.flush(); zos.close(); } // 以上,临时压缩文件创建完成 // 进行浏览器下载 // 获得浏览器代理信息 String agent = request.getHeader("User-Agent").toUpperCase(); // 判断浏览器代理并分别设置响应给浏览器的编码格式 String finalFileName = null; if (agent.contains("MSIE") || ((agent.indexOf("RV") != -1) && (agent.indexOf("FIREFOX") == -1))) { finalFileName = URLEncoder.encode(fileZip, "UTF-8"); } else { finalFileName = new String(fileZip.getBytes("UTF-8"), "ISO8859-1"); } response.setContentType("application/x-download");// 告知浏览器下载文件,而不是直接打开,浏览器默认为打开 response.setHeader("Content-disposition", String.format("attachment; filename=\"%s\"", finalFileName));// 下载文件的名称 //输出到本地 ServletOutputStream servletOutputStream = response.getOutputStream(); DataOutputStream temps = new DataOutputStream(servletOutputStream); DataInputStream in = new DataInputStream(new FileInputStream(filePath));// 浏览器下载临时文件的路径 byte[] b = new byte[2048]; File reportZip = new File(filePath);// 之后用来删除临时压缩文件 try { while ((in.read(b)) != -1) { temps.write(b); } temps.flush(); } catch (Exception e) { log.info("下载压缩包失败",e); } finally { if (temps != null) { temps.close(); } if (in != null) { in.close(); } if (reportZip != null) { reportZip.delete();// 删除服务器本地产生的临时压缩文件 } servletOutputStream.close(); } }
相关文章推荐
- php实现批量压缩图片文件大小的脚本
- android-调用系统的ContentPrivder获取单张图片实现剪切做头像及源码下载
- android-调用系统的ContentPrivder获取单张图片实现剪切做头像及源代码下载
- 提供下载:批量图片压缩(生成缩略图或指定大小图片)及文件批量改名器
- 【JAVA秒会技术之玩转图片】图片下载和等比或指定大小压缩快速实现
- Angular实现svg和png图片下载实现
- php实现批量压缩图片文件大小的脚本
- Asp.Net 文件操作基类(读取,删除,批量拷贝,删除,写入,获取文件夹大小,文件属性,遍历目录)(一)
- Asp.Net 文件操作基类(读取,删除,批量拷贝,删除,写入,获取文件夹大小,文件属性,遍历目录)(一)
- 缩略图实现,将图片(jpg、bmp、png、gif等等)真实的变成想要的大小
- Asp.Net 文件操作基类(读取,删除,批量拷贝,删除,写入,获取文件夹大小,文件属性,遍历目录)
- 不需要下载图片 获取网络图片大小
- java将图片缩放实现类(能将jpg、bmp、png、gif图片文件,进行等比或非等比的大小转换)
- .net+ajax+jquery.form实现简单的图片批量上传 含Demo源码下载
- Shell脚本实现批量下载网络图片代码分享
- ASP实现上传图片自动 压缩图片大小 留存待修改
- [导入]Asp.Net 文件操作基类(读取,删除,批量拷贝,删除,写入,获取文件夹大小,文件属性,遍历目录)(一)
- 利用Node 搭配uglify-js压缩js文件,批量下载图片到本地
- android 获取本地全部图片列表的实现及源码下载(二)
- 安卓中关于图片从网络获取,压缩,上传,下载,缩略图,缓存的一些处理总结(一)