/**
* 引用: 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 })
}