工作中和一个扫描仪厂家对接,厂家写了一个插件。
可以在客户的电脑上开启一个http服务供网页调取,以此实现网页和扫描仪的交互。
扫描仪工作完成后,调取一个接口,从本地的扫描结果中返回图片的base64。
然后,页面上再将base64一个个的传输到后台,获取服务器返回的url之后在系统中使用。
测试的时候,非常完美,但是实际使用的时候,却产生一个问题,客户的网络带宽比较低,导致上传图片的过程
就很慢。
于是我就想到一个优化的办法,在前端将图片压缩之后传输到后台,并且不能失真。扫描出来的图片大小只有
700~800k左右,体积已经比较小了,但是base64会导致数据包变大,一张图片的base64在1m以上。
首先,先将base64转换成二进制对象
var strData = atob(base64)
var charData = strData.split('').map(function(x) { return x.charCodeAt(0) })
var binData = new Uint8Array(charData)
然后,再用pako.js将数据压缩
var str = pako.gzip(binData);
最后一步发送数据的时候,遇到一个问题,我用jquery封装的ajax方法发送数据的时候,浏览器会直接卡死。
后来我在网上找到了一个用js原生方法的写法,就正常。
var oReq = new XMLHttpRequest();
oReq.open("POST", "后台url", true);
oReq.onload = function (oEvent) {
};
oReq.send(str);
后台使用@RequestBody byte[] 就能接收到数据
@PostMapping("/common/upimg")
@ResponseBody
public AjaxResult uploadBase64(@RequestBody byte[] data) throws Exception
{
try
{
String filePath = RuoYiConfig.getProfile() + "/fileImgs/";
String currentDir = DateUtils.datePath();
String fileName = UUID.randomUUID(true) + ".jpg";
FileUtil.writeBytes(ZipUtil.unGzip(data), filePath + currentDir + "/" + fileName);
String pathFileName = Constants.RESOURCE_PREFIX + "/fileImgs/" + currentDir + "/" + fileName;
String url = serverConfig.getUrl() + pathFileName;
AjaxResult ajax = AjaxResult.success();
ajax.put("fileName", pathFileName);
ajax.put("url", url);
return ajax;
}
catch (Exception e)
{
e.printStackTrace();
return AjaxResult.error(e.getMessage());
}
}
我这里是使用的ruoyi的后台通用上传方法修改的,解压是用的hutool封装的方法。
建议能找到封装好的工具的话,尽量用封装好的工具类。但是封装好的工具也不一定是完全满足要求的。
这个时候,就要自己尝试造轮子了。