base64图片压缩上传

base64图片压缩上传(前后端demo)

一、前端代码
	<input type="file" id="imgfile" method="post" enctype="multipart/form-data">
	<button type="button" onclick="ToBase64();">

js代码

function ToBase64() {
		var img = document.getElementById('imgfile')
    	var imgFile = new FileReader();
		if(img.files[0] != null){//判断是否选择了图片
			  imgFile.readAsDataURL(img.files[0]);
		}
		var imgData ="";
    	imgFile.onload = async function () {
				 var imgData = this.result; //base64数据
				 console.log(imgData.length);
				 var str = await dealImage1(imgData, 500);//图片压缩
				console.log(str.length);
				console.log(str);
				api.ajax({
					//这里是自己请求后台的方法
				});
   }
}

前端图片压缩方法,可以直接使用https://blog.csdn.net/zx19930309/article/details/90375907
但是他用的是回调方式不能完全满足我的需求,所以在同事的帮助下做出了一点更改

function dealImage1(base64, w) {
	return new Promise((res,ret) => {

		var newImage = new Image();
		var file = "";
		var quality = 0.6;    //压缩系数0-1之间
		newImage.src = base64;
		newImage.setAttribute("crossOrigin", 'Anonymous');	//url为外域时需要
		var imgWidth, imgHeight;
		newImage.onload = function () {
			imgWidth = this.width;
			imgHeight = this.height;
			var canvas = document.createElement("canvas");
			var ctx = canvas.getContext("2d");
			if (Math.max(imgWidth, imgHeight) > w) {
				if (imgWidth > imgHeight) {
					canvas.width = w;
					canvas.height = w * imgHeight / imgWidth;
				} else {
					canvas.height = w;
					canvas.width = w * imgWidth / imgHeight;
				}
			} else {
				canvas.width = imgWidth;
				canvas.height = imgHeight;
				quality = 0.6;
			}
			ctx.clearRect(0, 0, canvas.width, canvas.height);
			ctx.drawImage(this, 0, 0, canvas.width, canvas.height);
			var base64 = canvas.toDataURL("image/jpeg", quality); //压缩语句
			//如想确保图片压缩到自己想要的尺寸,如要求在50-150kb之间,请加以下语句,quality初始值根据情况自定
			while (base64.length / 1024 > 150) {
				quality -= 0.01;
				base64 = canvas.toDataURL("image/jpeg", quality);
			}
			//防止最后一次压缩低于最低尺寸,只要quality递减合理,无需考虑
			while (base64.length / 1024 < 50) {
				quality += 0.001;
				base64 = canvas.toDataURL("image/jpeg", quality);
			}
			file = base64;
			console.log(base64.length);
			console.log(file.length);
			res(file)
		}
	})
}
二、后台java代码

controller根据自己项目框架直接获取前端传递的字符串便可

public String fileUpload(String file) {
		//验证
		if(file == null || file.isEmpty()) {
			throw new MestarException("未找到文件!");
		}
		// 获取路径
		String fileUrl = mbfDocService.getFilePath();//这个按自己项目实际需求获取路径
		// 替换
		file = file.replaceAll(" ", "+");
		int index = file.indexOf(",");
		file = file.substring(index + 1);
		System.out.println(file);
		String name = TimeUtils.dateToString(new Date(), TimeUtils.DF_SIMPLE_YMDHMS);
		String fileName = name + "." + "jpg";
		File file1 = new File(fileUrl + fileName);
		try {
			// 解码,然后将字节转换为文件
			byte[] bytes = Base64.decodeBase64(file);// 将字符串转换为byte数组
			// byte[] bytes = Base64.getDecoder().decode(file);
			// 判断文件夹是否存在
			File targetFile = new File(fileUrl);
			if (!targetFile.exists()) {
				targetFile.mkdirs();
			}
			boolean copyByte2File = this.copyByte2File(bytes, file1);
			if (!copyByte2File) {
				throw new MestarException("上传失败!");
			} else {
				return fileName;
			}

		} catch (Exception ioe) {
			ioe.printStackTrace();
			throw new MestarException("上传失败!," + ioe.getMessage());
		}
	}

前端传递给后台base64字符串中会出现缺失被替换的情况
所有我把被替换的+号全部复原,并且将data:image/jpg;base64,开头截取掉

		file = file.replaceAll(" ", "+");
		int index = file.indexOf(",");
		file = file.substring(index + 1);

二进制流上传图片

public boolean copyByte2File(byte[] bytes, File file) {
		FileOutputStream out = null;
		try {
			// 转化为输入流
			ByteArrayInputStream in = new ByteArrayInputStream(bytes);

			// 写出文件
			byte[] buffer = new byte[1024];

			out = new FileOutputStream(file);

			// 写文件
			int len = 0;
			while ((len = in.read(buffer)) != -1) {
				out.write(buffer, 0, len); // 文件写操作
			}
			return true;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			try {
				if (out != null) {
					out.close();
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return false;
	}
三、java后台压缩

后台压缩使用Thumbnails进行压缩
引入依赖

<dependency>
      <groupId>net.coobird</groupId>
      <artifactId>thumbnailator</artifactId>
      <version>0.4.8</version>
    </dependency>

在上传时压缩,但是后台压缩会有一个弊端,虽然简单方便但是对于程序而言执行时间会比前端压缩更长
在这里插入图片描述
只用一行代码便可以实现

Thumbnails.of(in).scale(0.1f).toOutputStream(out);
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个示例代码,使用canvas将图片压缩为指定大小,然后将压缩后的base64字符串上传到服务器。 HTML代码: ```html <input type="file" id="file-input"> ``` JavaScript代码: ```javascript // 获取文件输入框元素 const fileInput = document.getElementById('file-input'); // 监听文件输入框变化事件 fileInput.addEventListener('change', () => { // 获取文件对象 const file = fileInput.files[0]; // 创建 FileReader 对象 const reader = new FileReader(); // 读取文件完成事件 reader.addEventListener('load', () => { // 创建图像对象 const img = new Image(); // 图像加载完成事件 img.addEventListener('load', () => { // 创建 canvas 对象 const canvas = document.createElement('canvas'); // 缩放比例 const scale = Math.min(800 / img.width, 800 / img.height); // 设置 canvas 大小 canvas.width = img.width * scale; canvas.height = img.height * scale; // 绘制图像到 canvas 中 const ctx = canvas.getContext('2d'); ctx.drawImage(img, 0, 0, canvas.width, canvas.height); // 将 canvas 转为 base64 字符串 const base64 = canvas.toDataURL('image/jpeg', 0.8); // 发送 base64 字符串到服务器 uploadBase64(base64); }); // 加载图像 img.src = reader.result; }); // 读取文件 reader.readAsDataURL(file); }); // 上传 base64 字符串到服务器 function uploadBase64(base64) { // 发送 AJAX 请求 // ... } ``` 这里使用 canvas 将图片压缩为指定大小,然后将压缩后的 base64 字符串上传到服务器。在实际开发中,还需要根据具体需求进行调整,比如调整压缩比例、设置图片格式、设置上传方式等等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值