热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

详解Java实现批量压缩图片裁剪压缩多种尺寸缩略图一键批量上传图片

10万+IT人都在关注的图片批量压缩上传方案(完整案例+代码) 背景需求:为了客户端访问图片资源时,加载图片更流畅,体验更好,通常不会直接

10万+IT人都在关注的图片批量压缩上传方案(完整案例+代码)

背景需求:为了客户端访问图片资源时,加载图片更流畅,体验更好,通常不会直接用原图路径,需要根据不同的场景显示不同规格的缩略图,根据商品关键属性,能够获取到图片不同尺寸规格的图片路径,并且能根据不同缩略图直观看到商品的关键属性,需要写一个Java小工具把本地磁盘中的图片资源一键上传至分布式FastDFS文件服务器,并把图片信息存入本地数据库,PC端或者客户端查询商品时,就可以根据商品的业务属性。比如根据productId就能把商品相关的不同尺寸规格的图片都获取到,页面渲染图片资源时,不同的场景,直接通过文件服务器的IP+存储路径,可以在线预览。

示例:商品id为1001的主图原图1001.jpg,大小为800×800(px),在本案例中解析为1001-50×50.jpg,1001-100×100.jpg,1001-200×200.jpg,1001-400×400.jpg,解析后连同原图就是5种尺寸规格的图片。前端就能直观的根据屏幕大小,业务场景等因素使用不同的图片。

实现思路:先把本地磁盘目录中的所有图片资源通过IO流读出来,读到内存中,然后对图片的名称根据定义好的业务规则解析,生成不同的图片名,然后对原图进行不同规格的解析压缩处理,以及图片资源的上传和图片信息的批量保存至数据库。

常用的压缩方案有下面2种:

方案一:对原图进行按照指定存储空间的压缩,比如原图100Kb,压缩至10Kb

方案二:对原图进行指定宽高大小的压缩,比如原图800*800,压缩至100*100

准备工作:封装一个文件流操作的通过工具类,如下:

package com.demo.utils;
 
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
 
import org.apache.tomcat.util.codec.binary.Base64;
 
/**
 * 创建时间:2019年3月13日 下午9:02:32
 * 项目名称:shsc-batchUpload-server
 * 类说明:文件流工具类
 * @author guobinhui
 * @since JDK 1.8.0_51
 */
public class FileUtils {
 
  /* 
   * 读取本地物理磁盘目录里的所有文件资源到程序内存 
   */ 
	public static List readFiles(String fileDir) {
	File dirPath = new File(fileDir);
	//用listFiles()获得子目录和文件
	File[] files = dirPath.listFiles();
	List list1 = new ArrayList();
	for (int i = 0; i 

封装一个压缩图片处理类

package com.demo.mapper.entity;
 
import java.awt.Image;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.imageio.ImageIO;
 
/**
 * 创建时间:2019年3月13日 下午3:35:05
 * 项目名称:shsc-batchUpload-server
 * 类说明:图片压缩处理类
 * @author guobinhui
 * @since JDK 1.8.0_51
 */
public class ImgCompress {
 
  private Image img; 
  private int width; 
  private int height;
  
  /** 
   * 构造函数 
   */ 
  public ImgCompress(String filePath) throws IOException { 
    File file = new File(filePath);// 读入文件 
    img = ImageIO.read(file);   // 构造Image对象 
    width = img.getWidth(null);  // 得到源图宽 
    height = img.getHeight(null); // 得到源图长 
  } 
	public Image getImg() {
		return img;
	}
	public void setImg(Image img) {
		this.img = img;
	}
	public int getWidth() {
		return width;
	}
	public void setWidth(int width) {
		this.width = width;
	}
	public int getHeight() {
		return height;
	}
	public void setHeight(int height) {
		this.height = height;
	}
  public void reSize(int w, int h,File file,String dir) throws IOException { 
    // SCALE_SMOOTH 的缩略算法 生成缩略图片的平滑度的 优先级比速度高 生成的图片质量比较好,但是速度慢 
     BufferedImage tag = new BufferedImage(50,50,BufferedImage.TYPE_INT_RGB );
	Image img = ImageIO.read(file);
	Image image = img.getScaledInstance(w, h, Image.SCALE_SMOOTH);
	tag.getGraphics().drawImage(image,50, 50, null); // 绘制缩小后的图 
	
	// 将输入文件转换为字节数组
	byte[] bytes = FileUtils.getByte(file);
	// 构造输入输出字节流
	ByteArrayInputStream is = new ByteArrayInputStream(bytes);
	ByteArrayOutputStream os = new ByteArrayOutputStream();
	double rate = w/800;//缩放比率
	try {
	 // 处理图片
	 zoomImage(is,os,rate);
	} catch (Exception e) {
	 e.printStackTrace();
	}
	// 将字节输出流写入文件
	FileUtils.writeFile(os,new File(dir+"/"+file.getName()));
  } 
  
  public void zoomImage(InputStream is, OutputStream os,double Rate) throws Exception { 
   BufferedImage bufImg = ImageIO.read(is);
   AffineTransformOp ato = new AffineTransformOp(AffineTransform.getScaleInstance(Rate,Rate), null);
   BufferedImage bufferedImage = ato.filter(bufImg, null);
   ImageIO.write(bufferedImage, "jpg", os);
 }
}

方案一具体实现过程:

package com.demo.controller;
 
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
 
import javax.imageio.ImageIO;
 
import org.apache.tomcat.util.codec.binary.Base64;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.demo.mapper.entity.AttachmentModel;
import com.demo.mapper.entity.ImgCompress;
import com.demo.mapper.entity.ProductPic;
import com.demo.service.IFileService;
import com.demo.utils.FileUtils;
import com.shsc.framework.common.ResultInfo;
 
/**
 * 创建时间:2019年3月8日 下午3:03:56
 * 项目名称:shsc-batchUpload-server
 * 类说明:图片批量压缩上传
 * @author guobinhui
 * @since JDK 1.8.0_51
 */
@RestController
@RequestMapping(value="/file")
public class FileController {
 
 
@Autowired
private IFileService fileServiceImpl;
 
 
@RequestMapping("/test")
@ResponseBody
public String test() {
 //原始图片目录
 String originalFileDir = "D:/pics/pic1";
 List  originalFileList = readFiles(originalFileDir);
 Iterator it = originalFileList.iterator();
 //压缩后的缩略图目录
 String thumbnailDir = "D:/uploadBaseDir/productPic/20190313/thumbnail";
 long startWrite = System.currentTimeMillis();
 while(it.hasNext()){
	File file = (File)it.next();
	try {
	 ImgCompress img = new ImgCompress(file.getPath());
	 img.reSize(50, 50, file, thumbnailDir);
	} catch (IOException e) {
	 // TODO Auto-generated catch block
	 e.printStackTrace();
	 return "上传失败!";
	} 	
  }
 long endWrite = System.currentTimeMillis();
 System.out.println("批量上传文件共计耗时:" +(endWrite-startWrite)/1000+"秒" );	
return "

批量上传文件成功,非常棒,压缩上传文件总数量为:"+num+",共计耗时"+(endWrite-startWrite)/1000+"秒

"; } }

最后在浏览器上访问该接口或者把该接口放在main方法里run,效果如下:

方案二具体实现过程:

@RequestMapping("/upload")
@ResponseBody
public String upload(){
	//win环境原始文件目录
	String originalFileDir = "D:/pics/pic1";
	System.out.println("读磁盘文件开始");
	long startRead = System.currentTimeMillis();
	List  originalFileList = readFiles(originalFileDir);
	long endRead = System.currentTimeMillis();
	System.out.println("读磁盘文件结束");
	System.out.println("读取磁盘文件共计耗时:" +(endRead-startRead)+"毫秒" );	
	
	Iterator it = originalFileList.iterator();
	System.out.println("压缩拷贝文件开始");
	long startWrite = System.currentTimeMillis();
//	Integer size = 500;//每500个图片批量插入一次
//	Integer i = 0;
	String productNumber = null;
	
	String thumbnailDir = "D:/uploadBaseDir/productPic/20190313/thumbnail";
	String base64 = null;
	String new50PicName = "";
	String new100PicName = "";
	String new200PicName = "";
	String new400PicName = "";
	List  picList = new ArrayList();
	int picType;
	List  sizeList = new ArrayList();
	sizeList.add(0,50);
	sizeList.add(1,100);
	sizeList.add(2,200);
	sizeList.add(3,400);
	
 while(it.hasNext()){
	File file = (File)it.next();
	System.out.println("原始文件路径为:"+file.getPath());
	String originalFileName= file.getName();
	String prefixName = originalFileName.substring(0,originalFileName.lastIndexOf("."));
	String ext = originalFileName.substring(originalFileName.lastIndexOf("."));
	
	byte[] buff = FileUtils.getByte(file);
	ByteArrayInputStream is = new ByteArrayInputStream(buff);
	ByteArrayOutputStream os = null;
	BufferedImage BI = null;
	base64 = getBase64(file);
	ResultInfo<&#63;> r = fileServiceImpl.uploadBase64(base64,originalFileName);
	AttachmentModel att = (AttachmentModel)r.getData();
	if(originalFileName.indexOf('-') == -1) {
	 picType = 1;
	 productNumber = prefixName;
	}else {
	 picType = 2;
	 productNumber = originalFileName.substring(0,originalFileName.lastIndexOf("-"));
	}
	if(r.isSuccess()) {
	 ProductPic pic = new ProductPic();
	 BeanUtils.copyProperties(att, pic);
	 pic.getPicName();
	 pic.setProductId(productNumber);
	 pic.setPicType(picType);
	 picList.add(pic);
	}
	if(originalFileName.indexOf('-') == -1) {//不带'-'的是商品主图
	 productNumber = prefixName;
	 new50PicName = productNumber+'-'+ "50×50"+ext;
	 new100PicName = productNumber+'-'+ "100×100"+ext;
	 new200PicName = productNumber+'-'+ "200×200"+ext;
	 new400PicName = productNumber+'-'+ "400×400"+ext;
	}else {
	 productNumber = originalFileName.substring(0,originalFileName.lastIndexOf("-"));
	 new50PicName = originalFileName.substring(0,originalFileName.lastIndexOf("."))+'-'+ "50×50"+ext;
	 new100PicName = originalFileName.substring(0,originalFileName.lastIndexOf("."))+'-'+ "100×100"+ext;
	 new200PicName = originalFileName.substring(0,originalFileName.lastIndexOf("."))+'-'+ "200×200"+ext;
	 new400PicName = originalFileName.substring(0,originalFileName.lastIndexOf("."))+'-'+ "400×400"+ext;
	}
	
	try {
	 File f = null;
	 BI = ImageIO.read(is);
	 for (int i = 0; i  rr = fileServiceImpl.uploadBase64(base64,f.getName());
		if(rr.isSuccess()) {
			AttachmentModel atta = (AttachmentModel)rr.getData();
			if(atta.getPicName().indexOf('-') == -1) {//不带'-'的是商品主图
				picType = 1;
			}else if(atta.getPicName().indexOf("-1.") != -1
					|| atta.getPicName().indexOf("-2.") != -1
					|| atta.getPicName().indexOf("-3.") != -1
					|| atta.getPicName().indexOf("-4.") != -1) {
				picType = 2;
			}else if((atta.getPicName().indexOf("-1-") == -1
					||atta.getPicName().indexOf("-2-") == -1
					||atta.getPicName().indexOf("-3-") == -1
					||atta.getPicName().indexOf("-4-") == -1)
					&& atta.getPicName().indexOf("-") != -1) {
				picType = 3;
			}else {
				picType = 4;
			}
			ProductPic pic = new ProductPic();
			BeanUtils.copyProperties(atta, pic);
			pic.getPicName();
			pic.setProductId(productNumber);
			pic.setPicType(picType);
			picList.add(pic);
		}
	} 
	} catch (Exception e1) {
		// TODO Auto-generated catch block
		e1.printStackTrace();
	}
}
int num = fileServiceImpl.insertPics(picList);
if(num > 0) {
	long endWrite = System.currentTimeMillis();
	System.out.println("批量上传文件共计耗时:" +(endWrite-startWrite)/1000+"秒" );	
	return "

批量上传文件成功,非常棒,压缩上传文件总数量为:"+num+",共计耗时"+(endWrite-startWrite)/1000+"秒

"; } return "批量上传文件失败!"; }

以上所述是小编给大家介绍的Java实现批量压缩图片裁剪压缩多种尺寸缩略图一键批量上传图片详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!


推荐阅读
  • 一、Hadoop来历Hadoop的思想来源于Google在做搜索引擎的时候出现一个很大的问题就是这么多网页我如何才能以最快的速度来搜索到,由于这个问题Google发明 ... [详细]
  • 这是原文链接:sendingformdata许多情况下,我们使用表单发送数据到服务器。服务器处理数据并返回响应给用户。这看起来很简单,但是 ... [详细]
  • 本文介绍了高校天文共享平台的开发过程中的思考和规划。该平台旨在为高校学生提供天象预报、科普知识、观测活动、图片分享等功能。文章分析了项目的技术栈选择、网站前端布局、业务流程、数据库结构等方面,并总结了项目存在的问题,如前后端未分离、代码混乱等。作者表示希望通过记录和规划,能够理清思路,进一步完善该平台。 ... [详细]
  • Oracle优化新常态的五大禁止及其性能隐患
    本文介绍了Oracle优化新常态中的五大禁止措施,包括禁止外键、禁止视图、禁止触发器、禁止存储过程和禁止JOB,并分析了这些禁止措施可能带来的性能隐患。文章还讨论了这些禁止措施在C/S架构和B/S架构中的不同应用情况,并提出了解决方案。 ... [详细]
  • 一句话解决高并发的核心原则
    本文介绍了解决高并发的核心原则,即将用户访问请求尽量往前推,避免访问CDN、静态服务器、动态服务器、数据库和存储,从而实现高性能、高并发、高可扩展的网站架构。同时提到了Google的成功案例,以及适用于千万级别PV站和亿级PV网站的架构层次。 ... [详细]
  • Linux服务器密码过期策略、登录次数限制、私钥登录等配置方法
    本文介绍了在Linux服务器上进行密码过期策略、登录次数限制、私钥登录等配置的方法。通过修改配置文件中的参数,可以设置密码的有效期、最小间隔时间、最小长度,并在密码过期前进行提示。同时还介绍了如何进行公钥登录和修改默认账户用户名的操作。详细步骤和注意事项可参考本文内容。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • 本文介绍了关于apache、phpmyadmin、mysql、php、emacs、path等知识点,以及如何搭建php环境。文章提供了详细的安装步骤和所需软件列表,希望能帮助读者解决与LAMP相关的技术问题。 ... [详细]
  • Android系统移植与调试之如何修改Android设备状态条上音量加减键在横竖屏切换的时候的显示于隐藏
    本文介绍了如何修改Android设备状态条上音量加减键在横竖屏切换时的显示与隐藏。通过修改系统文件system_bar.xml实现了该功能,并分享了解决思路和经验。 ... [详细]
  • 标题: ... [详细]
  • 本文总结了淘淘商城项目的功能和架构,并介绍了传统架构中遇到的session共享问题及解决方法。淘淘商城是一个综合性的B2C平台,类似京东商城、天猫商城,会员可以在商城浏览商品、下订单,管理员、运营可以在平台后台管理系统中管理商品、订单、会员等。商城的架构包括后台管理系统、前台系统、会员系统、订单系统、搜索系统和单点登录系统。在传统架构中,可以采用tomcat集群解决并发量高的问题,但由于session共享的限制,集群数量有限。本文探讨了如何解决session共享的问题。 ... [详细]
  • MySQL语句大全:创建、授权、查询、修改等【MySQL】的使用方法详解
    本文详细介绍了MySQL语句的使用方法,包括创建用户、授权、查询、修改等操作。通过连接MySQL数据库,可以使用命令创建用户,并指定该用户在哪个主机上可以登录。同时,还可以设置用户的登录密码。通过本文,您可以全面了解MySQL语句的使用方法。 ... [详细]
  • Servlet多用户登录时HttpSession会话信息覆盖问题的解决方案
    本文讨论了在Servlet多用户登录时可能出现的HttpSession会话信息覆盖问题,并提供了解决方案。通过分析JSESSIONID的作用机制和编码方式,我们可以得出每个HttpSession对象都是通过客户端发送的唯一JSESSIONID来识别的,因此无需担心会话信息被覆盖的问题。需要注意的是,本文讨论的是多个客户端级别上的多用户登录,而非同一个浏览器级别上的多用户登录。 ... [详细]
author-avatar
爱你想你疼你吻你_514
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有