900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > 微信小程序上传图片使用canvas添加水印

微信小程序上传图片使用canvas添加水印

时间:2021-03-26 00:32:35

相关推荐

微信小程序上传图片使用canvas添加水印

项目近期有一个需求,是在小程序上传图片或者选择多张图片时,页面缩略图和上传服务器的图片都是带水印的,水印文案是当前的时间和当前所处的地点。

<!-- 添加水印 --><view hidden = "{{ !watermark }}"><mp-uploader bindfail="uploadError" bindsuccess="uploadSuccess" binddelete="delete" select="{{selectFile}}" files="{{files}}" upload="{{uplaodFile2}}" max-count="{{maxCount}}" title="{{title}}" tips="{{tip}}"></mp-uploader><view style='width:0px;height:0px;overflow:hidden;position:fixed;left:90000000px;z-index:-999;'><canvas wx:for="{{canvasArray}}" wx:key="key" canvas-id="canvasId{{index}}" style="width: {{item.width}}px;height: {{item.height}}px;"></canvas></view></view><!-- 不添加水印 --><view hidden = "{{ watermark }}"><mp-uploader bindfail="uploadError" bindsuccess="uploadSuccess" binddelete="delete" select="{{selectFile}}" files="{{files}}" upload="{{uplaodFile}}" max-count="{{maxCount}}" title="{{title}}" tips="{{tip}}"></mp-uploader></view>

const app = getApp()const http = require('../../utils/http')// 引入SDK核心类var QQMapWX = require('../../utils/qqmap-wx-jssdk')//申请密钥地址var qqmapsdk = new QQMapWX({key: 'PBPBZ-HHOW3-4H63F-YZDHC-HAJP3-VJBSK' })Component({options: {styleIsolation: 'shared'},/*** 组件的属性列表*/properties: {files: {type: Array,value: []},title: {type: String,value: '图片上传'},tip: {type: String,value: ''},maxCount: {// 最多上传张数type: Number,value: 7},watermark: {type: Boolean,value: false}},/*** 页面的初始数据*/data: {canvasArray: [], // DOM创建canvas的数组pics: [], // 上传到服务器的图片promisePics: [], // 上传图片队列address: ''},ready: function () {this.setData({selectFile: this.selectFile.bind(this),uplaodFile: this.uplaodFile.bind(this),uplaodFile2: this.uplaodFile2.bind(this)})http.get('huawei/obs').then(res => {this.setData({huawei: res })})const that = thiswx.getLocation({isHighAccuracy: true, // 开启地图精准定位type: 'gcj02', // 地图类型写这个// type: 'wgs84',success: function(res) {//用腾讯地图的api,根据经纬度定位当前位置信息qqmapsdk.reverseGeocoder({location: {latitude: res.latitude, // 回调的纬度longitude: res.longitude // 回调的经度},//回调成功显示位置的详细数据success:(res)=> {that.setData({address: res.result.address })},//回调失败 (调用成功之后这个可以不需要 ,回调失败会有报错信息方便调试)fail: function (res) {console.log(res)},//成功失败都会执行complete: function (res) {console.log(res)}})},})},/*** 组件的方法列表*/methods: {selectFile (files) {// 返回false可以阻止某次文件上传},uplaodFile (files) {files.tempFilePaths.map(file => {const key = 'miniprogram/' + Math.random().toString(36).substr(2) + '.jpg';const formData = {};if (this.data.huawei) {formData.policy = this.data.huawei.policy;formData.signature = this.data.huawei.signature;formData.AWSAccessKeyId = this.data.huawei.AccessKeyId;formData['Content-Type'] = 'image/jpeg';}formData.key = key;wx.uploadFile({url: app.globalData.imgHost,header: {},filePath: file,name: 'file',formData: formData,success: (res) => {// console.log('success', res);if (res.errMsg == 'uploadFile:ok') {if ( typeof (res.header.Location) == 'string' ) {this.setData({files: [...this.data.files, {url: app.globalData.imgHost + (res.header.Location).substring(res.header.Location.indexOf('/miniprogram')) }]})} else {let location = (res.header.Location)[0]this.setData({files: [...this.data.files, {url: app.globalData.imgHost + location.substring(location.indexOf('/miniprogram')) }]})}this.triggerEvent('change', this.data.files.map(file => file.url))}},complete: (res) => {console.log('complete', res);}})})// 文件上传的函数,返回一个promisereturn new Promise((resolve, reject) => {resolve(this.data.files)})},// 上传图片 // 参数: filesuplaodFile2 (files) {wx.showLoading({title: "正在加载图片", mask: true })const {tempFilePaths } = files// 获取动态生成canvas的数组let canvasArr = tempFilePaths.map( item => {if (typeof item == 'string') {return {'url': item} } else {return item }})this.setData({canvasArray: canvasArr })this.uploadFileAll(tempFilePaths).then(res => {console.log("所有接口都请求完了", res)})// 图片上传的函数,返回Promise,Promise的callback里面必须resolve({urls})表示成功,否则表示失败return new Promise((resolve, reject) => {resolve({urls: this.data.promisePics })// 清空上传图片队列this.setData({promisePics: [] })})},uploadFileAll (tempFilePaths) {return new Promise( (resolve, reject) => {let arr2 = []tempFilePaths.map( (item, index) => {const promise = new Promise( (res, rej) => {this.imgPromise(item, index)res()})arr2.push(promise)})Promise.all(arr2).then((result) => {resolve() // 所有接口都执行完毕})} )},// 返回图片上传promiseimgPromise (item, index) {return new Promise( (resolve, reject) => {const that = thiswx.getImageInfo({src: item,success(res) {// 设置对应的canvas的宽高let canvasArray = that.data.canvasArraycanvasArray[index].width = res.widthcanvasArray[index].height = res.heightthat.setData({canvasArray: canvasArray })// canvas添加水印that.getCanvasImg(res, index).then(pImg => {resolve(pImg)}).catch(err => {reject(err)})}})})},// canvas添加水印getCanvasImg(imgInfo, index) {return new Promise( (resolve, reject) => {const that = thislet {path, width, height } = imgInfo// 图片添加水印// 获取当前时间let newDate = new Date()let year = newDate.getFullYear() //年let month = newDate.getMonth() + 1 //月let day = newDate.getDate() //日var hour = newDate.getHours()var minute = newDate.getMinutes()var second = newDate.getSeconds()let roleNameInfo = '拍摄时间:' + year + '年' + month + '月' + day + '日 '+ hour+':'+minute +':' + secondlet address = '上海市'// 创建canvasconst ctx = wx.createCanvasContext('canvasId'+index, that)ctx.drawImage(path, 0, 0, width, height) // 先画出图片// 将声明的时间放入canvaslet fontSize = 30if (width >= 1500) {fontSize = 80 } else if (width >= 1000) {fontSize = 60 }ctx.setFontSize(fontSize) //注意:设置文字大小必须放在填充文字之前,否则不生效ctx.setFillStyle('rgba(255, 255, 255, 0.5)')ctx.shadowOffsetX = -6 //用来设定阴影在 X轴的延伸距ctx.shadowOffsetX = -6 //用来设定阴影在 Y轴的延伸距ctx.shadowBlur = 3 //设定阴影的模糊程度 默认0ctx.shadowColor = "rgba(0, 0, 0, 0.3)" //设定阴影颜色效果ctx.fillText(roleNameInfo, 20, height/8)ctx.fillText(that.data.address, 20, height/8+fontSize+10)ctx.draw(false, function () {// 绘画完成回调// 生成图片 把当前画布指定区域的内容导出生成指定大小的图片。在 draw() 回调里调用该方法才能保证图片导出成功wx.canvasToTempFilePath({quality: 1,fileType: 'jpg',canvasId: 'canvasId'+index,// destWidth: width, // 输出的图片的宽度// destHeight: height, // 输出的图片的高度// width: width,// height: height,success: function (res) {that.handleUpload(res.tempFilePath).then( _=> {// res.tempFilePath 最终图片路径resolve()})},fail: function(res) {reject(res)}}, that)})})},// 上传图片方法handleUpload (img) {return new Promise( (resolve, reject) => {const that = thisconst key = 'miniprogram/' + Math.random().toString(36).substr(2) + '.jpg'const formData = {};if (that.data.huawei) {formData.policy = that.data.huawei.policyformData.signature = that.data.huawei.signatureformData.AWSAccessKeyId = that.data.huawei.AccessKeyIdformData['Content-Type'] = 'image/jpeg'}formData.key = keywx.uploadFile({url: app.globalData.imgHost,filePath: img,name: 'file',formData: formData,success: (res) => {wx.hideLoading()if(res.errMsg == 'uploadFile:ok') {// 上传成功let url = ''let {pics, promisePics } = that.datapromisePics.push( img )if ( typeof (res.header.Location) == 'string' ) {url = app.globalData.imgHost + res.header.Location.substring(res.header.Location.indexOf('/miniprogram'))} else {let location = (res.header.Location)[0]url = app.globalData.imgHost + location.substring(location.indexOf('/miniprogram'))}pics.push(url)that.setData({pics, promisePics, files: [...this.data.files, {url: url } ] })that.triggerEvent('change', this.data.files.map(file => file.url))}},fail: (error) => {wx.hideLoading()console.log('error', error)}})})},delete (e) {this.data.files.splice(e.detail.index, 1)this.setData({files: this.data.files })this.triggerEvent('change', this.data.files.map(file => file.url))},change: function () {this.triggerEvent('change', this.data)},uploadError(e) {console.log('upload error', e.detail)},uploadSuccess(e) {console.log('upload success', e.detail)}},export () {return this.data}})

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。