附件有含有源码下载
。
开篇背景:
在网上找了许多资料,汇总之后写了这么一个示例出来,现将完整代码整理处理,包括前端完整的Hbuilder工程代码和后端的处理上传Java实现。图片裁切使用到了jquery.cropper插件,所以这个图片裁切的功能模块是需要使用到jquery的,也尝试自己写了一点实现了基本的图片放大缩小、图片移动后感觉脑袋太晕了,还是找一款插件更加合适,经详细了解了cropper插件后觉得太强大了,兼容pc、安卓、ios等,一些特色功能满足来了我个人对于图片裁切所需要的所有,插件下载地址为:https://github.com/fengyuanchen/cropper ,网上也能找到需要关于此插件的在线运行,也可以将附件源码下载下来,在源码的docs/index.html文件打开可以直接运行代码示例。特色功能有:图片拖动大小缩放、背景图片移动、裁切区域移动、选区大小调整、选区移动、照片左右上下变换、旋转等,这些功能也是我本次示例中使用到了的。
后端处理:
无论用什么语言,它的目的是将用户裁切完成后的数据进行存储,由于前端裁切使用了canvas裁切图片,所以提交到后端的是裁切后的区域图片字符串编码,而非图片文件,后端需要将此字符串采用base64解码转换成一张图片文件存储。。。也就是说这里的后端处理文件上传并非传统的处理图片上传,而是解码base64字符串,如果还不清楚base64字符串编码与图片的转换,可以使用word验证一下。这里临时写了一个简单的Java的servlet程序来处理文件上传,参考代码如下:
package com;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.UUID;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.util.Base64;
import com.frame.base.utils.properties.PropertiesUtils;
import com.frame.base.utils.properties.enums.EnumProperties;
@WebServlet("/testaa.servlet")
public class Test extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String imageBase64 = req.getParameter("imageBase64");
//将base64的图片编码存储至服务器,并将路径修改至数据库
String type = "data:image/png;base64,";//前台是以png的格式存储的
imageBase64 = imageBase64.substring(type.length());
String realPath = "sysuser" + File.separator + UUID.randomUUID().toString() + ".png";
JSONObject json = new JSONObject();
try {
this.uploadFileByBase64(realPath , imageBase64);
json.put("result", "success");
json.put("message", realPath);
} catch (Exception e) {
json.put("result", "error");
json.put("message", "上传图片失败!");
e.printStackTrace();
}
//将参数输出至浏览器
PrintWriter out = resp.getWriter();
out.write(json.toJSONString());
out.flush();
out.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
this.doGet(req, resp);
}
public File uploadFileByBase64(String destRealPath , String imageBase64) throws Exception{
OutputStream out = null;
try {
byte bytes[] = Base64.decodeFast(imageBase64);
//这里是我的获取图片文件服务器的路径,可以是随便一个地址,如d:\\temp\\之类的
String imageServer = PropertiesUtils.getInstance().getProperty(EnumProperties.APPLICATION, "system.fileupload.information");
String destFilePath = imageServer + File.separator + destRealPath;
File destFile = new File(destFilePath);
if(! destFile.getParentFile().exists()){
destFile.getParentFile().mkdirs();
}
for(int i=0 , lens = bytes.length ; i < lens ; i++){
if(bytes[i] < 0){
bytes[i] += 256;
}
}
out = new FileOutputStream(destFile);
out.write(bytes);
return destFile;
} catch (Exception e) {
throw new Exception(e);
} finally {
if(out != null){
try {
out.flush();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
上传至服务器的图片下载
服务器端是我临时写的代码,如果示例提示上传失败,有可能是我的服务器关闭了无法正常访问,运行示例中提示的上传成功可将相关地址复制到浏览器访问,我的服务器会输出这个裁切后上传到服务器的图片,图片结尾地址为.image,即xxxxx.png.image
其他说明
前台代码中用到了一些windows.xxx没有别的意思,就是为了不想定义全部变量而已。