前言 想給本身的一些圖片加上水印,因而就搗騰了這麼個東西。
此功能沒有考慮兼容性(太懶了),只在Chrome下測試經過,若是您在什麼IE火狐下測試不經過就不要吐槽了。
由於應用了download屬性,因此IE什麼的就不用期望了,若是您是火狐瀏覽器的話,本身改一下兼容性應該是沒問題的。
代碼什麼的開了F12本身拿吧,沒有壓縮哦。(最後吐槽一下,原本代碼是貼進博客裏面的,保存爲草稿預覽的時候也能夠,結果在發佈後js代碼全被屏蔽了,最後只能寫到頁腳裏了。因此獲取js代碼到頁腳那裏獲取就行了)
固然你也能夠訪問下面這個github地址獲取代碼:代碼地址。
另外爲了弄進博客園,特地把代碼從ES2015改爲了ES5,因此多多少少有點亂,不過必要的註釋都加上去了,這麼辛苦,點個贊啊。
至於要改水印樣式什麼的,控制檯裏更改這個變量的屬性便可。php
var watermarkInfo = { fontSize: 18, // 像素值 fontFamily: 'cursive', content: '', color: '#fffbf0' };
廢話就很少說了,直接上做品。
選擇背景圖後,設置水印文字,而後拖動水印文字到任意位置,最後點擊下載文件按鈕便可。css
選擇背景圖 設置水印
html
實現過程當中的問題與解決方案 代碼什麼的就不所有貼上來了,只是講一下其中遇到的一些問題與實現思路。
這些問題您可能已經大多瞭解了,不過爲了兼顧全部人,因此仍是會將一些比較簡單的技術點也講一下。
整個實現過程當中遇到的問題以下
獲取圖片
將上傳文件轉換爲圖片
在圖片上加水印
拖動文字加水印
將最後修改的圖片下載下來
獲取圖片 獲取圖片實際上就是用到文件上傳控件,也就是git
<input id="target_file" type="file"/>
然而原始的文件上傳控件比較醜,因此隱藏此控件,並加了一個新的按鈕在它前面github
<a class="btn" id="btn_select_file" href="jacascript:void(0)">選擇背景圖</a> <input id="target_file" type="file" style="display:none" />
而想實現點擊選擇背景圖按鈕去選擇文件,用如下代碼便可canvas
// 按下選擇的背景圖 $('#btn_select_file').click(function () { $('#target_file').click(); });
選擇文件後,文件上傳控件會觸發change事件,此時能夠拿到文件。瀏覽器
$('#target_file').change(function (event) { var imgFile = event.target.files[0]; ...... });
將文件轉換爲圖片 文件轉換爲圖片實際上首先須要讀取文件,這裏須要用到FileReader。app
function setImgIntoCanvas(imgFile) { var reader = new FileReader(); reader.onloadend = function (e) { var dataURL = e.target.result; img.onload = function (event) { var ctx = document.getElementById('target_canvas').getContext('2d'); //將canvas大小設置爲和圖片同樣大 setCanvasSize(event.target.naturalWidth, event.target.naturalHeight); ctx.drawImage(img, 0, 0); setCanvasImgToDownloadLink(); }; img.src = dataURL; }; reader.readAsDataURL(imgFile); resetWatermark(); };
以上爲核心代碼,經過FileReader的readAsDataURL函數讀取文件能夠得到Base64格式的圖片數據,將圖片數據賦值給一個Image對象。
在圖片上加水印 看了上面的代碼,裏面就有一個步驟是將圖片渲染進canvas,實際上核心功能就是用canvas來給圖片加水印。
操做思路就是先將圖片用drawImage渲染進canvas,再在指定的位置用fillText渲染文字便可,並將最後的canvas用 toDataURL
轉化爲圖片數據便可。
具體的用法能夠參考個人代碼,而後查一下canvas的API便可。
這種在新手看來很難的東西說穿了其實很簡單,這裏就不講了。
可是接下來就麻煩了,若是是白色水印,圖片上加水印的地方確定不能和圖片色差過小,要否則很難發現。
因此針對不一樣的圖片,水印的位置確定須要可調整。
最開始的方案是給定兩個輸入框,而後輸入位置,接着渲染水印到文本上。
可是這個方案首先就面臨一個易用性的問題,我怎麼得到具體的位置呢,只能一個一個去試,並非每一個用戶都會用截圖軟件去找位置。
因此這裏採用拖動文字的方案。
拖動文字加水印 canvas雖然也能捕獲事件,獲取鼠標位置,並實現拖動文字效果,可是實現起來太麻煩。
因此這裏採用更簡單的方案。
當咱們設置水印時,直接將文字渲染到canvas上,而後在文字上方安放一個顏色透明的內容爲水印文字的span元素。
而後咱們在這個span元素上加drag事件。
HTML5拖動功能網上一大堆,這裏就不講了。
主要講一下實現思路:
在開始拖動時,從新用圖片渲染canvas,使得以前渲染的文字消失。
在結束拖動時,獲取到具體的位置,再從新將文字渲染進canvas。
這裏提及來簡單,其實仍是有一些細節,包括css和js的配合,好比文字拖動到邊界時的處理方式,又好比文字拖動到邊界出現換行的狀況。
還有一些其餘的小坑點,須要你本身看代碼去體會了。
這裏貼出部分代碼:編輯器
// 綁定移動水印相關事件 var bindEvent4DragWatermark = function () { $('#watermark').on('dragstart', function (e) { var ctx = document.getElementById('target_canvas').getContext('2d'); ctx.clearRect(0, 0, $('#target_canvas').width(), $('#target_canvas').height()); ctx.drawImage(img, 0, 0); // 顯示可拖拽水印 $(this).addClass('selected'); watermarkInfo.offsetX = e.originalEvent.offsetX + canvasInfo.left; watermarkInfo.offsetY = e.originalEvent.offsetY + canvasInfo.top; }); // 讓水印跟着鼠標移動 $('#watermark').on('drag', function (e) { var x = e.originalEvent.pageX; var y = e.originalEvent.pageY; if (x === 0 && y === 0) { return; } x -= watermarkInfo.offsetX; y -= watermarkInfo.offsetY; $('#watermark').css('left', x).css('top', y); }); $('#watermark').on('dragend', function (e) { // 調整位置,使水印沒法超出canvas邊界 var x = e.originalEvent.pageX - watermarkInfo.offsetX; var y = e.originalEvent.pageY - watermarkInfo.offsetY; if (x < 0) { x = 0; } if (y < 0) { y = 0; } var maxX = canvasInfo.width - watermarkInfo.width; var maxY = canvasInfo.height - watermarkInfo.height; if (x > maxX) { x = maxX; } if (y > maxY) { y = maxY; } $('#watermark').css('left', x).css('top', y); // 拖拽完水印,文本隱藏 $('#watermark').removeClass('selected'); setTextIntoCanvas(); }); // 讓鼠標不顯示禁用樣式 $('#canvas-container').on('dragover', function (e) { e.preventDefault(); }); }
將最後修改的圖片下載下來 以前咱們已經講到了用canvas的toDataURL函數獲取最後的圖片數據,而後關於下載就須要用到一個HTML5的download屬性。函數
<a class="btn" id="download_file" href="#" download="水印圖片">下載合成圖片</a>
接下來是設置圖片數據的代碼
/** * 設置canvas圖像到下載連接上 */ function setCanvasImgToDownloadLink() { var imgData = document.getElementById('target_canvas').toDataURL(); $('#download_file').attr('href', imgData); };
將功能寫進博客裏 至於這部分首先要申請JS權限。
其次若是觀察仔細,還能夠在個人代碼中看到下列代碼
// 此處經過這種方式將html插入,是由於博客園自動屏蔽了canvas標籤和download屬性 var initHtmlConstruct = function () { $('#canvas-container').text('').append('<canvas id="target_canvas" width="100" height="100">瀏覽器不支持此功能,請升級</canvas><span draggable="true" id="watermark"></span>') $('#toolbar').append('<a class="btn" id="download_file" href="#" download="水印圖片">下載合成圖片</a>'); }
至於緣由註釋裏也寫了,是由於博客園的編輯器屏蔽了canvas標籤和download屬性。
總結 總的來講,這實際上是一個很小的功能,可是要把它作得好用一點,涉及到的知識點並很多,也不併不只僅我提到的這一點(好比canvas的透明度樣式並非用圖片哦,而是用css樣式,仍是從《css揭祕》那本書上學到的)。
固然這個東西或多或少仍是有那麼一些瑕疵,也存在一些兼容性上的問題,不過對我而言夠用就好。
也但願上面介紹的一些東西對您也有收穫。
轉載於猿2048:➼《在博客園裏給圖片加水印(canvas + drag)》