您的位置:首页 > 其它

获取普通图片和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();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐