一.UEditor涂鸦功能
UEditor的涂鸦功能的实现原理是运用H5的标签(该标签用于在网页上绘制图形)供用户在浏览器上绘制2D图型,并通过JS的Base64加密后用Ajax异步提交至后台再经过Base64解密成betye字节数组再转化为输入流存储在服务器上的过程。
UEditor 涂鸦功能展示-用户进行涂鸦
UEditor涂鸦功能展示-回显在页面上
2.2动手整合ueditor涂鸦功能
2.2.1 关于ueditor.config.js
打开涂鸦按钮
找到 toolbar的定义处,并确保涂鸦按钮是开放状态,如下图所示
定义好涂鸦后台地址
然后在本文件中定义好涂鸦的后台访问地址,如下图所示
2.2.2 关于scrawl.js
本文件涉及到涂鸦前端如何将图片提交到后台,以及前端如何回显等问题
后台方法入口
原代码664行
将原代码getActionUrl注释掉,并添加以下代码,重新定义后台服务入口及参数
varcontextRootPath = editor.getOpt(‘contextRootPath’);
var actionUrl =contextRootPath+editor.getOpt(‘scrawlActionName’),
params =‘filetype=scrawl’;
浏览器控制台打印输出涂鸦图片的后台地址前端图片回显
原代码642行
重新定义了涂鸦图片回显链接
浏览器控制台打印输出涂鸦图片的回显链接地址
2.2.2 后台代码实施涂鸦图片服务端存储
后台服务
/**
* 涂鸦上传
* @param response
* @param request
* @return
* @throws Exception
*/
@ResponseBody
@RequestMapping(value="/scrawlUpload",method = RequestMethod.POST)
public Map<String, Object> scrawlUpload(HttpServletResponse response,
HttpServletRequest request)throws Exception{
Map<String, Object> params = new HashMap<String, Object>();
String filetype = request.getParameter("filetype");
System.out.println("filetype:"+filetype);
String upfile = request.getParameter("upfile");//Base64编码过的图片数据信息,对字节数组字符串进行Base64解码
System.out.println("upfile:"+upfile);
String basePath = "";
if("scrawl".equals(filetype)){
basePath = LoadPropertiesDataUtils.getValue("lixy.uploading.url.scrawl");
}
if(basePath == null || "".equals(basePath)){
basePath = "d:/lixy/static"; //与properties文件中lyz.uploading.url相同,未读取到文件数据时为basePath赋默认值
}
String fileName = String.valueOf(System.currentTimeMillis()).concat("_").concat(RandomUtils.getRandom(6)).concat(".").concat("png");
StringBuilder sb = new StringBuilder();
//拼接保存路径
sb.append(basePath).append("/").append(fileName);
// 在自己的项目中构造出一个用于存放用户照片的文件夹
File f = new File(sb.toString());
if (!f.exists()) {
f.getParentFile().mkdirs();
}
// 使用BASE64对图片文件数据进行解码操作
BASE64Decoder decoder = new BASE64Decoder();
try {
// 通过Base64解密,将图片数据解密成字节数组
byte[] bytes = decoder.decodeBuffer(upfile);
// 构造字节数组输入流
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
// 读取输入流的数据
BufferedImage bi = ImageIO.read(bais);
// 将数据信息写进图片文件中
ImageIO.write(bi, "png", f);// 不管输出什么格式图片,此处不需改动
params.put("state", "SUCCESS");
params.put("url", sb.toString());
params.put("size", upfile.length());
params.put("original", fileName);
params.put("type", "png");
bais.close();
} catch (IOException e) {
e.printStackTrace();
}
return params;
}
以上方法实现了涂鸦图片上传至后台后完成Base64解码并存储至服务器指定位置的功能
applications.properties配置服务端涂鸦图片存储路径
涂鸦图片后台存储路径设置
涂鸦生成图片存储在服务器指定目标
至于图片读取方法viewImagesToPage在上篇文章里有解释,这里就不重复了
三、UEditor视频功能
3.1 关于纠正上篇博文附件上传部分的纰漏
关于上一篇博文附件上传部分的代码有纰漏,如果不用到视频上传的功能,该纰漏可以被隐藏掉,但如果读者需要使用Ueditor的视频上传及播放功能,那么这个纰漏则必须修复。
上篇博文在谈到文件上传路径时提到webuploader.js 6199行
其实webuploader.js作为整个web端文件上传的入口,文件类型filetype=file写死在这里是不合适的(关键原因是视频上传功能也要用到这段代码)。
正确的处理方式应该是以下代码(参考)
那么对应的文件上传attachment.js也由以下
改为以下即可 actionUrl = actionUrl+’?filetype=file’
3.2 关于webuploader.js
关于webuploader.js 6199行部分代码应该按3.1节介绍的那样进行调整去掉参数filetype=file,如不然,会影响到视频上传的业务逻辑。
3.3 关于ueditor.config.js
该文件是ueditor最重要的配置文件,后台配置基本定义在此。
这里定义了videoActionName,videoFieldName,videoUrlPrefix,videoMaxSize,videoAllowFiles等视频上传必须用到的参数设置
videoActionName:
定义了视频上传后台类及方法 比如 /resource/upload/images (参考UploadImageController)
videoUrlPrefix:
视频访问路径 比如 /ueditor/resource/upload/fileDownLoad.do?(参考UploadImageController)
3.4 关于video.js
l 视频提交后台路径
原码第376行,建议不用getActionUrl获得actionUrl
采用 actinotallow= editor.getOpt(‘videoActionName’) 直接获得ueditor.config.js中定义好的videoActionName
在actionUrl末尾追加”?filetype=video”做为参数传至后台
l 视频前端播放路径
原码第294行 url:uploadDir + file.url,建议改为
url: uploadDir + file.url+’&filename=’+file.original,
其中uploadDir来自先前在ueditor.config.js中定义好的videoUrlPrefix
视频前端播放路径定义
浏览器控制台输出
3.5 视频上传控制类UploadImageController
本类是实现视频上传至服务指定目录的指定服务类,同时也是视频文件实现在线播放的服务类,与配置文件ueditor.config.js中定义的以下参数有关联
videoActionName:
定义了视频上传后台类及方法 比如 /resource/upload/images
videoUrlPrefix:
视频文件在线播放后台方法 比如 /ueditor/resource/upload/fileDownLoad.do?
代码参考如下
视频文件上传及存储方法images
/**
* 上传图片
* @param file
* @param request
* @param response
* @return MultipartFile uploadFile,
*/
@ResponseBody
@RequestMapping(value="/images",method = RequestMethod.POST)
public Map<String, Object> images (@RequestParam(value = "file", required = false) MultipartFile file, HttpServletRequest request, HttpServletResponse response){
Map<String, Object> params = new HashMap<String, Object>();
if (file == null){
System.out.println("未获得上传文件!");
return null;
}
try{
String filetype = request.getParameter("filetype")+"";
System.out.println("filetype:"+filetype);
String basePath = "";
if("image".equals(filetype)){
basePath = LoadPropertiesDataUtils.getValue("lixy.uploading.url.image");
}else if("file".equals(filetype)){
basePath = LoadPropertiesDataUtils.getValue("lixy.uploading.url.file");
}else if("video".equals(filetype)){
basePath = LoadPropertiesDataUtils.getValue("lixy.uploading.url.video");
}
if(basePath == null || "".equals(basePath)){
basePath = "d:/lixy/static"; //与properties文件中lyz.uploading.url相同,未读取到文件数据时为basePath赋默认值
}
System.out.println("filename:"+file.getOriginalFilename());
String ext = StringUtils.getExt(file.getOriginalFilename());
String fileName = String.valueOf(System.currentTimeMillis()).concat("_").concat(RandomUtils.getRandom(6)).concat(".").concat(ext);
StringBuilder sb = new StringBuilder();
//拼接保存路径
sb.append(basePath).append("/").append(fileName);
String visitUrl = basePath.concat("/"+fileName);
File f = new File(sb.toString());
if(!f.exists()){
f.getParentFile().mkdirs();
}
OutputStream out = new FileOutputStream(f);
FileCopyUtils.copy(file.getInputStream(), out);
params.put("state", "SUCCESS");
params.put("url", visitUrl);
params.put("size", file.getSize());
params.put("original", fileName);
params.put("type", file.getContentType());
params.put("filename", file.getOriginalFilename());
System.out.println("url:"+visitUrl+" original:"+fileName+" filename:"+file.getOriginalFilename()+" type:"+file.getContentType());
} catch (Exception e){
params.put("state", "ERROR");
e.printStackTrace();
}
return params;
}
视频文件在线播放方法fileDownLoad
/**
* 下载文件
* @param request
* @param response
* @return
* @throws IOException
*/
@RequestMapping(value = "/fileDownLoad",method = RequestMethod.GET)
public void fileDownLoad(HttpServletRequest request, HttpServletResponse response) throws IOException {
// 下载本地文件
String url = request.getParameter("url")+"";
String fileName = request.getParameter("filename")+"";
//如果是IE浏览器,则用URLEncode解析
if(isMSBrowser(request)){
fileName = URLEncoder.encode(fileName, "UTF-8");
}else{//如果是谷歌、火狐则解析为ISO-8859-1
fileName = new String(fileName.getBytes("UTF-8"), "ISO-8859-1");
}
System.out.println("filename:"+fileName+" url:"+url);
// 读到流中
InputStream inStream = new FileInputStream(url);// 文件的存放路径
// fileName = url.substring(url.lastIndexOf("/")+1);
// System.out.println("filename:"+fileName);
// 设置输出的格式
response.reset();
// response.setContentType("bin");
response.setContentType("application/vnd.ms-excel;charset=utf-8");
response.addHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
// 循环取出流中的数据
byte[] b = new byte[100];
int len;
try {
while ((len = inStream.read(b)) > 0)
response.getOutputStream().write(b, 0, len);
inStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
细心的读者可能已经看出来了,这不就是下载文件的方法吗?没错,就是这样的,在线视频播放后台支撑方法就是普通文件下载方法,( 因为本质是从后台读取文件字节流)
3.6 关于视频上传服务器存储路径的问题
对视频文件的存储路径定义在applications.properties文件中
后台的UploadImageController将对请求参数的不同将图片和附件存放在不同的目录中
3.7 关于ueditor.all.js
原码17772行,将image改为video
四、UEditor 音频功能
4.1 请参照第三章节介绍的视频功能
由于Ueditor默认的音频功能是去网上搜索音乐,这里介绍意义不大,由于第3章节已经完整介绍了Ueditor本地视频上传及在线播放的功能,同理音频文件也是可以按视频文件处理的,唯一不同的地方是,在线播放时没有图像(它是音频嘛)目前能支持的视、音频文件格式有
“.flv”, “.swf”,".mkv", “.avi”, “.rm”, “.rmvb”,".mpeg", “.mpg”,
“.ogg”, “.ogv”,".mov", “.wmv”, “.mp4”, “.webm”,".mp3", “.wav”, “.mid”
Ueditor默认支持的音频插件
使用整合后的视频插件实现音频文件上传及在线播放
上传成功后,点击播放按钮即开始在线播放音乐
五、案例分享
本文提供的完全与文章内容一致的案例,可供读者实际在本地运行
5.1 案例下载地址
5.2 运行准备工作
请参考上一篇博文
5.3 运行效果展示
在线视频加涂鸦
视频在线播放
涂鸦按钮和视频上传按钮如下图左侧和右侧