天天看點

UEditor富文本編輯器整合經驗分享(二)

一、引言          

       12月23日在部落格上給大家分享了一篇《 UEditor富文本編輯器整合經驗分享(整合至SpringMVC)》文章(http://blog.csdn.net/lixinyao5281/article/details/78878774),主要内容是介紹了一下UEditor整合及使用,解決了圖檔上傳、圖檔回顯、檔案上傳、檔案下載下傳等大家常關心的富文本應用的問題,至于擴充問題,比如 塗鴉、視訊、音頻播放這些更進階的内容并未涉及,今天本文主要來探讨一下這幾個進階一些的UEditor功能的整合使用,及前背景代碼的關鍵點。本文解決的主要問題是UEditor塗鴉後生成圖檔上傳、存儲、頁面顯示和視訊、音頻檔案(如mp4,mp3等)上傳、存儲、頁面線上播放的功能。

UEditor富文本編輯器整合經驗分享(二)

塗鴉生成圖檔上傳并回顯

UEditor富文本編輯器整合經驗分享(二)

上傳視訊檔案并線上播放

二、UEditor塗鴉功能

2.1 ueditor塗鴉功能介紹

    UEditor的塗鴉功能的實作原理是運用H5的<canvas>标簽(該标簽用于在網頁上繪制圖形)供使用者在浏覽器上繪制2D圖型,并通過JS的Base64加密後用Ajax異步送出至背景再經過Base64解密成betye位元組數組再轉化為輸入流存儲在伺服器上的過程。  

UEditor富文本編輯器整合經驗分享(二)

UEditor 塗鴉功能展示-使用者進行塗鴉

UEditor富文本編輯器整合經驗分享(二)

UEditor塗鴉功能展示-回顯在頁面上

2.2動手整合ueditor塗鴉功能

2.2.1 關于ueditor.config.js

打開塗鴉按鈕

找到 toolbar的定義處,并確定塗鴉按鈕是開放狀态,如下圖所示

UEditor富文本編輯器整合經驗分享(二)

定義好塗鴉背景位址

然後在本檔案中定義好塗鴉的背景通路位址,如下圖所示

UEditor富文本編輯器整合經驗分享(二)

2.2.2 關于scrawl.js

本檔案涉及到塗鴉前端如何将圖檔送出到背景,以及前端如何回顯等問題

背景方法入口 

UEditor富文本編輯器整合經驗分享(二)

原代碼664行

将原代碼getActionUrl注釋掉,并添加以下代碼,重新定義背景服務入口及參數

varcontextRootPath = editor.getOpt('contextRootPath');

var actionUrl =contextRootPath+editor.getOpt('scrawlActionName'),

params ='filetype=scrawl';

UEditor富文本編輯器整合經驗分享(二)

浏覽器控制台列印輸出塗鴉圖檔的背景位址

前端圖檔回顯

UEditor富文本編輯器整合經驗分享(二)

原代碼642行

重新定義了塗鴉圖檔回顯連結

UEditor富文本編輯器整合經驗分享(二)

浏覽器控制台列印輸出塗鴉圖檔的回顯連結位址

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配置服務端塗鴉圖檔存儲路徑

UEditor富文本編輯器整合經驗分享(二)

塗鴉圖檔背景存儲路徑設定

UEditor富文本編輯器整合經驗分享(二)

塗鴉生成圖檔存儲在伺服器指定目标 

至于圖檔讀取方法viewImagesToPage在上篇文章裡有解釋,這裡就不重複了

三、UEditor視訊功能

3.1 關于糾正上篇博文附件上傳部分的纰漏

     關于上一篇博文附件上傳部分的代碼有纰漏,如果不用到視訊上傳的功能,該纰漏可以被隐藏掉,但如果讀者需要使用Ueditor的視訊上傳及播放功能,那麼這個纰漏則必須修複。

上篇博文在談到檔案上傳路徑時提到webuploader.js 6199行

UEditor富文本編輯器整合經驗分享(二)

其實webuploader.js作為整個web端檔案上傳的入口,檔案類型filetype=file寫死在這裡是不合适的(關鍵原因是視訊上傳功能也要用到這段代碼)。

正确的處理方式應該是以下代碼(參考)

UEditor富文本編輯器整合經驗分享(二)

那麼對應的檔案上傳attachment.js也由以下

UEditor富文本編輯器整合經驗分享(二)

改為以下即可 actionUrl = actionUrl+’?filetype=file’

UEditor富文本編輯器整合經驗分享(二)

3.2  關于webuploader.js

      關于webuploader.js 6199行部分代碼應該按3.1節介紹的那樣進行調整去掉參數filetype=file,如不然,會影響到視訊上傳的業務邏輯。

3.3 關于ueditor.config.js

    該檔案是ueditor最重要的配置檔案,背景配置基本定義在此。

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 

UEditor富文本編輯器整合經驗分享(二)

采用 actionUrl= 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

UEditor富文本編輯器整合經驗分享(二)

視訊前端播放路徑定義

UEditor富文本編輯器整合經驗分享(二)

浏覽器控制台輸出

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檔案中

UEditor富文本編輯器整合經驗分享(二)

 背景的UploadImageController将對請求參數的不同将圖檔和附件存放在不同的目錄中

UEditor富文本編輯器整合經驗分享(二)
UEditor富文本編輯器整合經驗分享(二)

3.7 關于ueditor.all.js

 原碼17772行,将image改為video

UEditor富文本編輯器整合經驗分享(二)
UEditor富文本編輯器整合經驗分享(二)
UEditor富文本編輯器整合經驗分享(二)
UEditor富文本編輯器整合經驗分享(二)

四、UEditor 音頻功能

4.1  請參照第三章節介紹的視訊功能

     由于Ueditor預設的音頻功能是去網上搜尋音樂,這裡介紹意義不大,由于第3章節已經完整介紹了Ueditor本地視訊上傳及線上播放的功能,同理音頻檔案也是可以按視訊檔案處理的,唯一不同的地方是,線上播放時沒有圖像(它是音頻嘛)目前能支援的視、音頻檔案格式有

".flv", ".swf",".mkv", ".avi", ".rm", ".rmvb",".mpeg", ".mpg",

                              ".ogg", ".ogv",".mov", ".wmv", ".mp4", ".webm",".mp3", ".wav", ".mid"

UEditor富文本編輯器整合經驗分享(二)

Ueditor預設支援的音頻插件

UEditor富文本編輯器整合經驗分享(二)

使用整合後的視訊插件實作音頻檔案上傳及線上播放

UEditor富文本編輯器整合經驗分享(二)

上傳成功後,點選播放按鈕即開始線上播放音樂

五、案例分享

    本文提供的完全與文章内容一緻的案例,可供讀者實際在本地運作

5.1  案例下載下傳位址

http://download.csdn.net/download/lixinyao5281/10184662

5.2 運作準備工作

       請參考上一篇博文

5.3 運作效果展示

UEditor富文本編輯器整合經驗分享(二)

線上視訊加塗鴉

UEditor富文本編輯器整合經驗分享(二)

視訊線上播放

塗鴉按鈕和視訊上傳按鈕如下圖左側和右側

UEditor富文本編輯器整合經驗分享(二)

繼續閱讀