H5神器之canvas應用——網頁修改保存圖片


因為最近項目上的要求,需要在頁面中可以對一張圖片進行塗改和添加文字,然后再保存到(服務器)本地,因為也是第一次接觸這方面的,然后爬網頁啊爬網頁,之后發現了一款adobe開發的一款插件,適合 Anroid Ios 和Web的調用

傳送門 :感謝 翩翩 大神  http://www.cnblogs.com/hiflora/p/4267705.html

發現這款插件非常的炫酷,功能也還是蠻強大的。但是萬萬沒想到!!!當時也沒有注意大神的使用說明:

1,需要在線注冊賬號,申請apikey,地址:https://creativesdk.adobe.com/docs/web,這個apikey在代碼調用時需要。這里也有詳細的api文檔,其他功能請參考文檔說明,不過文檔是英文的。

2,要編輯的圖片必須有固定的地址,可以被網絡訪問到。

因為項目處理的圖片我覺得應該不會有啥固定的地址吧,可以被網絡訪問到,我想更加不是現實的吧,到時候項目中保存的圖片應該都是在本地的服務器上面,到時候有可能用的網絡是在局域網用的,要訪問這張圖片應該是很難的吧,最后放棄了!!

但是我覺得這個插件非常的炫酷,而且我覺得應該是蠻實用的,雖然點開頁面反應時間有點長了點,但是人家功能叼啊。

好了廢話不多說了,進入主題。

在扯幾句,之后跟同事聊天的時候說起這件事,然后同事說可以用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修改限制上傳大小 

 

以上就是這次記錄的全部內容,如有不足,請指教!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM