今天记录下,html5图片canvas压缩后上传,上传时的数据是formdata中的Blob封装数据,然后到servlet中将图片读取出来。
技术点:1、canvas画板压缩图片。(这个网上很多代码,我这里压缩效果不好,2M的图片压缩后还有1M)。
2、上传数据。这里是通过 XMLHttpRequest()上传的,也可以用Ajax上传。数据最终传的时Blob数据。
3、后台servlet读取文件。
遇到的坑、坑坑:1、canvas压缩网上很多,眼花缭乱,开始时候,抄完不知道最好数据在哪。
2、上传是用base64直接上传还是用form表单上传,还是用Ajax异步上传。
3、后台Servlet,读取文件,根据第二坑,一直在网上找过各种写法。
a、base64获取转码最后生产图片;此坑坑了我很久,获取到了base64字符串,生产不了图片。没解决,换方法了。
b、form上传,简单,上传的原始文件,没有压缩,不知道压缩后的图片怎么通过form表单上传,试了很多次,都是源文件,没压缩。
c、 XMLHttpRequest()上传的Blob数据。这个也是,我一直不知道怎么获取Blob数据,我都不知道传过去的是什么。这里写下,最后传过去的数据格式:
{name = blob ......... isFormField =false FieldName=imageFile}
不知道 name 和 filedName怎么生成的,我前端Ajax ,jqury知识太少。
下面上代码:
···<body onload="init();">
<div class="hintStr">
<h1>******</h1>
</div>
<div class="imgBox">
<img id="originimage" src="<%=path %>/img/temp.png" alt=""/>
</div>
<div class="menuBox clear">
<a id="photo" href="#">拍照
<input id="fileCamera" type="file" onchange="selectImage(this);" accept="image/*" capture="camera"/>
</a>
<input id="sendButton" type="button" onclick="uploadImage();" value="发送" />
</div>
<canvas id="compress"></canvas>
<div id=result ></div>
</body>
<script>
// 初始化
function init() {
var fileCamera = document.getElementById('fileCamera');
fileCamera.onchange = function () {
var fileList = fileCamera.files;
var file = fileList[0];
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function (evt) {
// 显示用户拍照图片
document.getElementById('originimage').src = evt.target.result;
// 图片载入画布
showCanvas(evt.target.result);
}
// 发送按键显示
document.getElementById('sendButton').style.display = 'inline';
}
}
// 压缩处理
function showCanvas(dataUrl) {
var img = new Image();
img.src = dataUrl;
img.onload = function () {
var canvasCompress = document.getElementById('compress');
var ctx = canvasCompress.getContext('2d');
var width = img.width , height = img.height;
var scal = width/height;
alert(scal);
canvasCompress.width = 700; //这里设置了压缩后图片的宽
canvasCompress.height =700/scal;
alert(canvasCompress.height);
// 图片压缩比例(长,宽)
ctx.scale(1, 1);
ctx.drawImage(img, 0, 0,width,height,0,0, canvasCompress.width, canvasCompress.height);
}
}
// 图片上传
function uploadImage(){
var canvasCompress = document.getElementById('compress');
var data = canvasCompress.toDataURL("image/jpg",0.01);
var formData = new FormData();
console.log("成功创建对象:"+formData);
formData.append("imageFile", convertBase64UrlToBlob(data));
var xhr= new XMLHttpRequest();
xhr.open('POST', 'ImageServlet');
xhr.onreadystatechange = function(){
if (xhr.readyState== 4&& xhr.status== 200){
console.log('上传成功'+xhr.responseText);
$("#result").append("<p>"+xhr.responseText+"</p>");
}
};
xhr.send(formData);
}
// 数据打包
function convertBase64UrlToBlob(urlData){
var bytes = window.atob(urlData.split(',')[1]);
var ab = new ArrayBuffer(bytes.length);
var ia = new Uint8Array(ab);
for (var i = 0; i < bytes.length; i++) {
ia[i] = bytes.charCodeAt(i);
}
return new Blob( [ab] , {type : 'image/jpg'});
}
</script>
servlet代码:
···protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// TODO Auto-generated method stub
// this.doGet(request, response);
request.setCharacterEncoding("utf-8");// 设置编码
response.setContentType("text/html;charset=UTF-8");
response.setCharacterEncoding("utf-8");
PrintWriter out = response.getWriter();
DiskFileItemFactory factory = new DiskFileItemFactory();// 获取磁盘文件条目工厂
// 设置文件上传路径
String uploadPath = this.getServletContext().getRealPath("/") + "photo";
// System.out.println(uploadPath);
File file = new File(uploadPath);
if (!file.exists()) {
file.mkdirs();
}
// 获取系统默认的临时文件保存路径,该路径为Tomcat根目录下的temp文件夹
String temp = System.getProperty("java.io.tmpdir");
// 设置临时文件夹为temp
factory.setRepository(new File(temp));
factory.setSizeThreshold(1024 * 1024 * 5);// 设置缓存大小为5M
// 用工厂实例化上传组件,ServletFileUpload用来解析文件上传请求
ServletFileUpload upload = new ServletFileUpload(factory);
try {
List<FileItem> items = upload.parseRequest(request);
Map param = new HashMap();
for (Object object : items) {
FileItem fileItem = (FileItem) object;
if (fileItem.isFormField()) {
param.put(fileItem.getFieldName(), fileItem.getString("utf-8"));// 如果你页面编码是utf-8的
} else {
String imgName = UUID.randomUUID().toString().replace("-", "") + ".jpg";// 生成名字
if (isOSLinux()) {
path = uploadPath + "/" + imgName;
}else {
path = uploadPath + "\" + imgName;}
System.out.println("=======================" + path + "==========");
InputStream is = fileItem.getInputStream();
inputStream2File(is, path);
Thread.sleep(10000);
File imgFile = new File(path);
if (imgFile.exists()) {
HttpRequest hRequest = new HttpRequest();
String result = hRequest.sendGet(url, path);
out.print(result.toString());
}
}
}
} catch (FileUploadException e) {
response.getWriter().println("图片上传失败:" + e.getMessage());
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
System.out.println("图片写入磁盘失败!");
response.getWriter().println("图片写入磁盘失败:" + e.getMessage());
}
out.flush();
out.close();
// response.getWriter().append("Served at:
// ").append(request.getContextPath()+"/photo");
}
// 流转化成字符串
public static String inputStream2String(InputStream is) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int i = -1;
while ((i = is.read()) != -1) {
baos.write(i);
}
return baos.toString();
}
// 流转化成文件
public static void inputStream2File(InputStream is, String savePath) throws Exception {
System.out.println("文件保存路径为:" + savePath);
File file = new File(savePath);
InputStream inputSteam = is;
BufferedInputStream fis = new BufferedInputStream(inputSteam);
FileOutputStream fos = new FileOutputStream(file);
int f;
while ((f = fis.read()) != -1) {
fos.write(f);
}
fos.flush();
fos.close();
fis.close();
inputSteam.close();
}
// 判断系统是否是Linux,如果是需要修改“\”,为“/"
public static boolean isOSLinux() {
Properties prop = System.getProperties();
String os = prop.getProperty("os.name");
if (os != null && os.toLowerCase().indexOf("linux") > -1) {
return true;
} else {
return false;
}
}