自適配傳資料 加水印 資料 Watermark.js
阿新 • • 發佈:2018-11-26
/** * 引用: import * as Watermark from '@/utils/canvas/watermark' // js外掛放置的 工具類目錄 * demo: <input class="upload-item-input" type="file" accept="image/*" name="file" @change="PreviewImage(e)"/> * 使用示例: const newFile = e.target.files[0] * Watermark.addWatermark(file, watermarkData, function(base64Codes) { // console.log('callback-base64Codes', base64Codes) const blob = Watermark.convertBase64UrlToBlob(base64Codes) const { lastModified, type } = newFile const watermark_file = new File([blob], imgName, { type: type, lastModified: lastModified }) // console.log('watermark_file', watermark_file) that.uploadImgObj.attachImgSrc = base64Codes // 加了水印 圖片base64顯示 // that.upload(watermark_file, imgName) // 上傳圖片 }) * @param file imgFile * @param data:[item] 水印數列 * @param callback 回撥 * @item { font, fillStyle, fillText, position } 單個水印 * @font font: '20px 黑體', 水印字型設定 * @fillStyle fillStyle: 'rgba(255,255,255,0.5)' rgba(255,255,255,0.5) or #f00 * @fillText fillText: '我是文案' * @position position: { horizontal, horizontalMargin, vertical, verticalMargin } 定位位置 * @data 傳入的示例陣列資料結構 this.watermarkData = [ { font: '20px 黑體', fillStyle: '#fff', fillText: '2018-07-06 星期五 江西省xxxxx', position: { horizontal: 'center', // 水平方向居 (left,right,center) horizontalMargin: '0', // 水平方向居 margin vertical: 'bottom', // 垂直方向居 (top,bottom,middle) verticalMargin: '20' // 垂直方向居 margin } }, { font: '40px 黑體', fillStyle: '#fff', fillText: '我是文案2', position: { horizontal: 'center', // 水平方向居 (left,right,center) horizontalMargin: '0', // 水平方向居 margin vertical: 'bottom', // 垂直方向居 (top,bottom,middle) verticalMargin: '46' // 垂直方向居 margin } } ] */
export function addWatermark(file, data, callback) { var ready = new FileReader() /* 開始讀取指定的Blob物件或File物件中的內容. 當讀取操作完成時,readyState屬性的值會成為DONE,如果設定了onloadend事件處理程式,則呼叫之.同時,result屬性中將包含一個data: URL格式的字串以表示所讀取檔案的內容.*/ ready.readAsDataURL(file) // 呼叫reader.readAsDataURL()方法,把圖片轉成base64 ready.onload = function() { var re = this.result canvasDataURL(re, data, callback) } } function canvasDataURL(path, data, callback) { const watermarkData = data const img = new Image() img.src = path img.onload = function() { const that = this // 預設按比例壓縮 let w = '' let h = '' const scale = that.width / that.height // 如果圖片尺寸太大,當圖片原尺寸寬度大於800 時,設定新圖片 寬度為800 ,高度並等比例縮放 if (that.width > 800) { w = 800 h = w / scale } else { w = that.width h = that.height } // 生成canvas const canvas = document.createElement('canvas') const ctx = canvas.getContext('2d') // 建立屬性節點 const anw = document.createAttribute('width') anw.nodeValue = w const anh = document.createAttribute('height') anh.nodeValue = h canvas.setAttributeNode(anw) canvas.setAttributeNode(anh) ctx.drawImage(that, 0, 0, w, h) // 需要加的水印陣列 for (const f in watermarkData) { const item = watermarkData[f] // console.log('canvasDataURL()-item', item) ctx.font = item.font ctx.fillStyle = item.fillStyle // 計算繪製水印的位置 // const itemHorizontalPadding = 0 || f * item. // 主要用於 多個水印之間 垂直方向的間隔 let positionX = 0 let positionY = 0 let textAlign = '' // 水平方向 switch (item.position.horizontal) { case 'left': positionX = item.position.horizontalMargin textAlign = 'left' break case 'right': positionX = w - item.position.horizontalMargin textAlign = 'right' break case 'center': positionX = w / 2 textAlign = 'center' } let textBaseline = '' // 垂直方向 switch (item.position.vertical) { case 'top': positionY = item.position.verticalMargin textBaseline = 'top' break case 'bottom': positionY = h - item.position.verticalMargin textBaseline = 'bottom' break case 'middle': positionY = h / 2 textBaseline = 'middle' } ctx.textAlign = textAlign // 水平居中 ctx.textBaseline = textBaseline // 垂直居中 ctx.fillText(item.fillText, positionX, positionY) } // 回撥函式返回base64的值 const base64 = canvas.toDataURL('image/jpeg', 1) callback(base64) } } /** * 將以base64的圖片url資料轉換為Blob * @param urlData * 用url方式表示的base64圖片資料 */ export function convertBase64UrlToBlob(urlData) { const arr = urlData.split(',') const mime = arr[0].match(/:(.*?);/)[1] const bstr = atob(arr[1]) let n = bstr.length const u8arr = new Uint8Array(n) while (n--) { u8arr[n] = bstr.charCodeAt(n) } return new Blob([u8arr], { type: mime }) }