由於最近項目上的要求,須要在頁面中能夠對一張圖片進行塗改和添加文字,而後再保存到(服務器)本地,由於也是第一次接觸這方面的,而後爬網頁啊爬網頁,以後發現了一款adobe開發的一款插件,適合 Anroid Ios 和Web的調用javascript
傳送門 :感謝 翩翩 大神 http://www.cnblogs.com/hiflora/p/4267705.htmlhtml
發現這款插件很是的炫酷,功能也仍是蠻強大的。可是萬萬沒想到!!!當時也沒有注意大神的使用說明:java
1,須要在線註冊帳號,申請apikey,地址:https://creativesdk.adobe.com/docs/web,這個apikey在代碼調用時須要。這裏也有詳細的api文檔,其餘功能請參考文檔說明,不過文檔是英文的。web
2,要編輯的圖片必須有固定的地址,能夠被網絡訪問到。spring
由於項目處理的圖片我以爲應該不會有啥固定的地址吧,能夠被網絡訪問到,我想更加不是現實的吧,到時候項目中保存的圖片應該都是在本地的服務器上面,到時候有可能用的網絡是在局域網用的,要訪問這張圖片應該是很難的吧,最後放棄了!!canvas
可是我以爲這個插件很是的炫酷,並且我以爲應該是蠻實用的,雖然點開頁面反應時間有點長了點,可是人家功能叼啊。segmentfault
好了廢話很少說了,進入主題。api
在扯幾句,以後跟同事聊天的時候提及這件事,而後同事說能夠用H5的canvas,忽然靈光一閃,由於之前看過這個介紹、可是沒有用過,以爲想一想可行,因而就嘗試這用canvas了。跨域
具體的canvas的他自帶的屬性我就不一一介紹了 傳送門 http://www.w3school.com.cn/tags/html_ref_canvas.asp服務器
上代碼HTML部分代碼:
1 <!DOCTYPE html> 2 <html xmlns="http://www.w3.org/1999/xhtml"> 3 <head runat="server"> 4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> 5 <title>demo</title> 6 </head> 7 <body> 8 <div> 9 <canvas id="canvas" ></canvas> 10 <img src="11.png" id="showPic" onclick="getPic()" > 11 </div> 12 <input type="text" name="fillWords" id="fillWords"> <button onclick="addWords()">文字添加</button> 13 <button onclick="cleanPic()">清空</button> 14 <button onclick="savePic()">保存</button> 15 </body> 16 </html>
下面是js代碼 感謝 http://www.oschina.net/code/snippet_221942_46198
1 <script type="text/javascript"> 2 3 //全局變量 4 var x_words, y_words; //用於得到鼠標點擊的座標 用於插入文字 5 var flag = false; 6 var canvas, ctxl; 7 8 canvas = document.getElementById('canvas'); 9 canvas.addEventListener('mousemove', onMouseMove, false); 10 canvas.addEventListener('mousedown', onMouseDown, false); 11 canvas.addEventListener('mouseup', onMouseUp, false); 12 13 canvas.addEventListener('touchstart', onMouseDown, false); 14 canvas.addEventListener('touchmove', onMouseMove, false); 15 canvas.addEventListener('touchend', onMouseUp, false) 16 17 canvas.height = 400; 18 canvas.width = 600; 19 20 ctx = canvas.getContext('2d'); 21 ctx.lineWidth = 3.0; // 設置線寬 22 ctx.strokeStyle = "#CC0000"; // 設置線的顏色 23 24 function onMouseMove(evt) { 25 evt.preventDefault(); 26 if (flag) { 27 var p = pos(evt); 28 ctx.lineTo(p.x, p.y); 29 x_words = p.x; 30 y_words = p.y; 31 ctx.lineWidth = 1.0; // 設置線寬 32 ctx.shadowColor = "#CC0000"; 33 ctx.shadowBlur = 1; 34 //ctx.shadowOffsetX = 6; 35 ctx.stroke(); 36 } 37 } 38 39 function onMouseDown(evt) { 40 evt.preventDefault(); 41 ctx.beginPath(); 42 var p = pos(evt); 43 ctx.moveTo(p.x, p.y); 44 flag = true; 45 } 46 47 function onMouseUp(evt) { 48 evt.preventDefault(); 49 flag = false; 50 } 51 52 function cleanPic() { 53 ctx.clearRect(0, 0, canvas.width, canvas.height); 54 } 55 56 function pos(event) { 57 var x, y; 58 if (isTouch(event)) { 59 x = event.touches[0].pageX; 60 y = event.touches[0].pageY; 61 } else { 62 x = event.layerX; 63 y = event.layerY; 64 } 65 return {x: x, y: y}; 66 } 67 68 function isTouch(event) { 69 var type = event.type; 70 if (type.indexOf('touch') >= 0) { 71 return true; 72 } else { 73 return false; 74 } 75 } 76 77 //添加文字 78 function addWords() { 79 var words = document.getElementById("fillWords").value; 80 ctx.fillStyle = "#CC0000"; 81 ctx.font = "20px 微軟雅黑"; 82 ctx.fillText(words, x_words, y_words); // 文字 83 } 84 85 function savePic() { 86 var pic = document.getElementById('showPic'); 87 // 獲得了須要保存的 相關圖的信息 格式爲:data:image/png;base64,xxxx" 有效的爲xxxx部分 88 var strDateUrl = canvas.toDataURL("image/png"); 89 pic.src = strDateUrl; 90 } 91 92 function getPic() { 93 var pic = document.getElementById('showPic'); 94 // pic.crossOrigin = "anonymous"; 95 ctx.drawImage(pic, 0, 0, 600, 400); 96 } 97 </script>
運行的效果圖以下:
原本,在這期間也遇到了一個問題: 由於我本來的打算是在 有背景的前提下面對於畫面的更改,由於需求就是對圖片的更改,以後保存麼,因此目的是更改圖片可是,當我點擊圖片的時候,雖然畫布背景改變了,也能夠添加文字和繪製一些亂七八糟的線條,可是在保存這圖片的時候報了下面的錯誤:
通過網上查詢 發現是圖片跨域的問題,這個名詞 我之前都沒聽過 :( 此次又學習到了新知識 我查看的資料:傳送門 感謝這位同窗!
可是,舊的問題解決了,新的問題又來了,當我爲圖片添加 crossOrigin = "anonymous"; 屬性的時候,我在服務器上面是可有用的,也能夠運行,可是把因此代碼都提取出,就不能夠運行了。就會報上面的錯。
下面順便也把保存圖片到本地 的方法寫出來吧, 通過post提交以後,後臺接受到提交過百的Base64值,轉換成二進制以後,寫到流文件中
1 package com.sl.apps.acs.services.server; 2 3 import com.cnblogs.yjmyzz.utils.FileUtil; 4 import org.springframework.stereotype.Service; 5 import sun.misc.BASE64Decoder; 6 7 import java.io.File; 8 import java.io.FileNotFoundException; 9 import java.io.FileOutputStream; 10 import java.io.IOException; 11 12 /** 13 * @author xueyuan 14 * @dater 2016-11-9 0009. 15 */ 16 @Service 17 public class Base64ToImageService { 18 19 public void Base64ToImageService(String imgStr) { 20 String currentDir = FileUtil.currentWorkDir; 21 String path = "images/1.jpg"; 22 saveImage(decode(imgStr.substring(22)),currentDir+path); 23 } 24 25 26 public static byte[] decode(String s) { 27 BASE64Decoder decoder = new BASE64Decoder(); 28 byte[] bytes = null; 29 try { 30 bytes = decoder.decodeBuffer(s); 31 } catch (IOException e) { 32 e.printStackTrace(); 33 } 34 return bytes; 35 } 36 37 38 public void saveImage(byte[] imageBytes,String path){ 39 File file=new File(path); 40 FileOutputStream outputStream=null; 41 try { 42 outputStream=new FileOutputStream(file); 43 outputStream.write(imageBytes); 44 } catch (FileNotFoundException e) { 45 e.printStackTrace(); 46 } catch (IOException e) { 47 e.printStackTrace(); 48 } finally{ 49 closeSteam(outputStream); 50 } 51 } 52 53 public void closeSteam(FileOutputStream outputStream){ 54 if(outputStream!=null){ 55 try { 56 outputStream.close(); 57 } catch (IOException e) { 58 e.printStackTrace(); 59 } 60 } 61 } 62 63 }
在解決保存的時候又發現了新的問題,由於我用的是jetty爲容器的,沒有設置maxFormContentSize 這個屬性,由於post的不能超過2M的數據,因此要把這個屬性設置爲你須要的大小 或者爲-1,即不限制大小:
感謝這位同窗: jetty修改限制上傳大小
以上就是此次記錄的所有內容,若有不足,請指教!