项目近期有一个需求,是在小程序使用相机拍照时,页面缩略图和上传服务器(或保存本地)的都是带水印的,水印文案是当前的时间和当前所处的地点。

前期使用了微信小程序的wx.chooseImage相机拍照,再使用拍摄后的图片添加水印,上传或者保存本地,这样做发现,每保存一次,相册里面都添加了两张图片,测试后发现,wx.chooseImage相机拍照默认保存到相册了,这样的话就会有问题,后期就改成了自己调用相机上传图片,发现是可以实现的,代码如下:

camera.wxml:

<view class="cameraWrapper" hidden="{{ markPhoto }}"><view class='camera'><camera wx:if="{{isAuth}}" device-position="back" flash="off" binderror="error"></camera></view><view class="btn-group"><mp-icon class="iconBtn returnBtn" icon="previous" color="#666" size="34" bindtap="returnCarmera"></mp-icon><button class="takePhoto" type="primary" plain="{{true}}" bindtap="camera"><text></text></button></view><!-- 添加水印 --><view class="canvas-cont"><canvas canvas-id='firstCanvas' style="width: {{w}}px;height: {{h}}px;"></canvas></view>
</view><!-- 拍摄后生成水印图片 -->
<view class="camera-cont" hidden="{{ !markPhoto }}"><view class="preview-image-cont"><image class="preview-image" src="{{markPhoto}}" mode="aspectFit"></image></view><view class="btn-group btn-group-padding" style="{{ markPhoto=='' ? 'display:none' : ''}}"><mp-icon class="iconBtn" icon="previous" color="#666" size="44" bindtap="againBtn"></mp-icon><icon class="icon-box-img" type="success" size="60" bindtap="saveBtn"></icon></view>
</view>

camera.js:

const util = require('../../../utils/util')
const app = getApp()
Page({data: {isAuth: false,markPhoto: null,prePage: null // 从哪个页面进入},onLoad: function (options) {this.setData({ prePage: options.page })wx.showLoading({ title: "正在加载中...", mask: true })app.globalData.pageName = this // 将globalData的页面指向自己const that = thiswx.getSetting({success: res => {if (res.authSetting['scope.camera']) {// 用户已经授权wx.hideLoading()that.setData({ isAuth: true })} else {// 用户还没有授权,向用户发起授权请求wx.authorize({scope: 'scope.camera',success() { // 用户同意授权wx.hideLoading()that.setData({ isAuth: true })},fail() { // 用户不同意授权that.openSetting().then(res => {wx.hideLoading()that.setData({ isAuth: true })})}})}},fail: res => {wx.hideLoading()console.log('获取用户授权信息失败')}})},// 打开授权设置界面openSetting: function () {const that = thislet promise = new Promise((resolve, reject) => {wx.showModal({title: '授权',content: '请先授权获取摄像头权限',success(res) {if (res.confirm) {wx.openSetting({success(res) {if (res.authSetting['scope.camera']) { // 用户打开了授权开关resolve(true)} else { // 用户没有打开授权开关, 继续打开设置页面that.openSetting().then(res => { resolve(true) })}},fail(res) {console.log(res)}})} else if (res.cancel) {that.openSetting().then(res => { resolve(true) })}}})})return promise;},// 服务站端-水印相机-调用摄像头拍照camera: function () {const that = thisif (app.globalData.address) {const ctx = wx.createCameraContext()ctx.takePhoto({quality: 'normal',success: (res) => {// console.log('res拍照', res)wx.showLoading({ title: "正在加载图片...", mask: true })that.addMark(res.tempImagePath)},fail (error) {wx.showToast({ title: error.errMsg, icon: 'none', duration: 2000 })setTimeout( () => { wx.navigateBack() }, 2000)}})} else {wx.showModal({ title: '提示', content: '请先授权获取当前地理位置',success (res) {if (res.confirm) {app.getLocation('again')} else if (res.cancel) {wx.navigateBack()}}})}},// 获取图片信息addMark: function (file) {const that = thiswx.getImageInfo({src: file,success(res2) {that.getCanvasImg(res2)}})},// 服务站端-相机-canvas添加水印getCanvasImg: function (imgInfo) {wx.showLoading({ title: "图片努力生成中...", mask: true })const that = thisconst today = util.formatTime(new Date())const addressTxt = app.globalData.addresslet { path, width, height } = imgInfothat.setData({ w: width, h: height }) // 720 1206// 创建canvasconst ctx = wx.createCanvasContext('firstCanvas', that)ctx.drawImage(path, 0, 0, width, height) // 先画出图片 地址,在canvas上X轴的位置,在canvas上y轴的位置,图片的宽度,图片的高度let fontSize = 30let rectY = height - 140let rectH = 140let imgWidth = 100let timeY = height - 80let addressY = height - 40let logoX = width - 120let logoY = height - 120let txtMaxWidth = width - imgWidth - 80if (addressTxt.length > 20) {rectY = height - 180rectH = 180imgWidth = 140timeY = height - 120addressY = height - 76logoX = width - 160logoY = height - 160txtMaxWidth = width - imgWidth - 80}ctx.setFontSize(fontSize) //注意:设置文字大小必须放在填充文字之前,否则不生效ctx.setFillStyle('rgba(0, 0, 0, .3)')ctx.fillRect(0, rectY, width, rectH)ctx.drawImage('/assets/images/logo.png', logoX, logoY, imgWidth, imgWidth)ctx.setFillStyle('rgba(255, 255, 255, 1)')ctx.fillText(today, 30, timeY)if (addressTxt.length < 20) {ctx.fillText(addressTxt, 30, addressY)} else {var chr = addressTxt.split("");//这个方法是将一个字符串分割成字符串数组var temp = "";var row = [];for (var a = 0; a < chr.length; a++) {if (ctx.measureText(temp).width < txtMaxWidth) {temp += chr[a];} else {a--; //这里添加了a-- 是为了防止字符丢失,效果图中有对比row.push(temp);temp = "";}}row.push(temp); // 如果数组长度大于2 则截取前两个if (row.length > 2) {var rowCut = row.slice(0, 2);var rowPart = rowCut[1];var test = "";var empty = [];for (var a = 0; a < rowPart.length; a++) {if (ctx.measureText(test).width < 460) {test += rowPart[a];} else {break;}}empty.push(test);var group = empty[0] + "..." // 这里只显示两行,超出的用...表示rowCut.splice(1, 1, group);row = rowCut;}for (var b = 0; b < row.length; b++) {ctx.fillText(row[b], 30, addressY + b * 40, txtMaxWidth);}}ctx.draw(false, (() => {setTimeout( () => {// 生成图片把当前画布指定区域的内容导出生成指定大小的图片。在 draw() 回调里调用该方法才能保证图片导出成功wx.canvasToTempFilePath({quality: 0.5,fileType: 'jpg',canvasId: 'firstCanvas',success: function (res) {wx.hideLoading()that.setData({ 'markPhoto': res.tempFilePath })},fail: function(error) {wx.hideLoading()wx.showToast({ title: error.errMsg, icon: 'none', duration: 2000 })}}, that)}, 100)})())},// 重拍againBtn: function () {this.setData({ 'markPhoto': null })},// 保存图片到相册saveBtn: function () {const that = thisif (that.data.prePage == 'complete') {let pages = getCurrentPages() // 获取当前页面let prePage = pages[pages.length - 2] // 获取上一页面prePage.setData({'markPhoto': that.data.markPhoto     //给上一页面的变量赋值})prePage.uploadMark(that.data.markPhoto) // 调用上一页面的方法(加载数据)wx.navigateBack({ delta: 1 }) // 返回上一页面} else {wx.saveImageToPhotosAlbum({ // 保存图片到系统相册filePath: that.data.markPhoto,success(res) {that.setData({ 'markPhoto': null })}})}},// 相机返回returnCarmera: function () {wx.navigateBack()}
})

camera.json:

{"component": true,"usingComponents": {"mp-icon": "weui-miniprogram/icon/icon"},"enablePullDownRefresh": true}

camera.wxss:


/* 模拟相机 */
.cameraWrapper {width: 100vw;height: 100vh;display: flex;flex-direction: column;
}
.camera {flex: 1;width: 100%;position: relative;
}
.camera camera {width: 100vw;height: calc(100vh - 200rpx);box-sizing: border-box;
}
.btn-group {position: relative;height: 200rpx;background-color: #fff;display: flex;align-items: center;justify-content: space-around;
}
.btn-group button.takePhoto:not([size='mini']) {position: relative;width: 120rpx;height: 120rpx;border-radius: 50%;border-width: 4rpx;
}
.btn-group button.takePhoto:not([size='mini']) text {position: absolute;top: 0;bottom: 0;left: 0;right: 0;width: 90rpx;height: 90rpx;border-radius: 50%;margin: auto;background-color: #07c160;
}
.btn-group .iconBtn {border: 4rpx solid #666;border-radius: 50%;
}
.btn-group .returnBtn {position: absolute;bottom: 19%;left: 14%;
}
.cameraWrapper .canvas-cont {width: 0px;height: 0px;position: fixed;left: 90000000px;z-index: -999;overflow: hidden;
}/* 拍摄后生成水印图片 */
.camera-cont {width: 100vw;height: 100vh;
}
.camera-cont .preview-image-cont {height: calc(100% - 200rpx);width: 100%;display: flex;align-items: center;justify-content: center;
}
.camera-cont .preview-image {width: 100%;height: 100%;
}
.camera-cont .btn-group-padding {padding: 0 12%;
}
.camera-cont .icon-box-img {margin-top: -4rpx;
}

let pages = getCurrentPages() // 获取当前页面
let prePage = pages[pages.length - 2] // 获取上一页面
prePage.setData({‘markPhoto’: that.data.markPhoto}) //给上一页面的变量赋值
prePage.uploadMark(that.data.markPhoto) // 调用上一页面的方法(加载数据)
– prePage.uploadMark()是调用上一个页面的方法

// 页面调用子组件的方法
uploadMark: function (markPhoto) {
this.selectComponent(‘#uploadMarkId’).handleUpload(markPhoto)
},
uploadMarkChoose: function (pictureSource) {
this.selectComponent(‘#uploadMarkId’).chooseImage(pictureSource)
}

微信小程序调用相机选择图片生成水印相关推荐

  1. 微信小程序拍照视频上传php,微信小程序-拍照或选择图片并上传文件

    微信小程序-拍照或选择图片并上传文件 调用拍照API:https://mp.weixin.qq.com/debug/wxadoc/dev/api/media-picture.html?t=201612 ...

  2. 微信小程序朋友圈分享图片生成方案实现

    在小程序界里,生成图片分享到朋友圈这个功能,是如此得光芒耀眼,以至于各个小程序都趋之若鹜地前来跪倒在她的石榴裙下.不幸的是,微信爸爸并没有提供给我们很好很便捷的相关工具:恰恰相反,屏幕截屏的功能被残忍 ...

  3. 微信小程序调用python分析图片_小帅丶干货之图像识别在微信小程序展示

    第一步肯定是去http://ai.baidu.com 注册账号,登陆并注册创建应用. http://ai.baidu.com/docs#/Begin/top 具体操作就看百度给出的文档即可很详细的哦. ...

  4. 微信小程序调用相机相册功能实现

    这个其实很简单,微信提供了api 1 一般我们做个人图像选择的时候可以简单的使用 click1:function(){wx.chooseImage({success: function(res) {} ...

  5. 微信小程序 — 打开相册选择图片功能

    点击页面的相册按钮如何打开系统相册.选择图片: <text class="nav-item1" bindtap="navToalbum">相册< ...

  6. 微信小程序调用相册和相机

    首先来写好wxml部分:给一个图片列表(img_list)和上传图片的按钮(addimg) <view class="container"><view class ...

  7. 微信小程序-从相册获取图片,视频 使用相机拍照,录像上传+服务器(nodejs版)接收

    在本文 微信小程序-从相册获取图片 使用相机拍照 本地图片上传之前需要看看 微信小程序-获取用户session_key,openid,unionid - 后端为nodejs 代码封装是在上文添加的. ...

  8. 微信小程录制视频上传服务器,微信小程序-从相册获取图片,视频使用相机拍照,录像上传+服务器nodejs版接收-微信小程序视频上传功能-微信小程序视频上传...

    在本文微信小程序-从相册获取图片使用相机拍照本地图片上传之前需要看看微信小程序-获取用户session_key,openid,unionid-后端为nodejs代码封装是在上文添加的.本文知识点:1. ...

  9. uni开发微信小程序自定义相机自动检测(人像+身份证)

    之前开发过微信小程序自定义相机拍照检测人像和身份证检测.一直期望写篇文章记录一下,趁现在有点时间,总结一下. 需求点: 1.能够自定拍摄人像 2.能够自动拍摄身份证正面照 3.识别身份证并且和人脸照比 ...

最新文章

  1. db2 修改表空间自增长_db2表空间及日志文件调整
  2. ArrayList集合的使用和源码详细分析
  3. 根据使用频率为 5 个字符设计的哈夫曼编码不可能是( )
  4. android查看存储占用,Android获取App内存使用情况的方法
  5. 不禁网页的浏览器_网页游戏兴衰史:「农场」没有菜,「渣渣辉」不贪玩
  6. 苹果已招聘两名梅赛德斯前工程师 其中一人曾在保时捷工作近6年
  7. Maven学习总结(50)——Maven Dependency的 Scope 属性详解
  8. 爬虫_淘宝(selenium)
  9. Google搜索技巧大全:101个谷歌搜索技巧推荐
  10. cat6 万兆_千兆网线和万兆网线有什么区别?
  11. php云人才伪静态,骑士cms(骑士人才系统)伪静态设置方法
  12. 极致cms精纺资源网的模板
  13. 手机RAM、ROM和储存卡的那些事
  14. JS初中段考:袖珍西历
  15. TimeQuest Timing Analyzer简单使用
  16. linux运行python
  17. 【SAP-MM】收货发票的总账科目是在哪里定义的?
  18. TOEFL口语模板--小站
  19. MacAppStore的魅力4点
  20. Microsoft Office

热门文章

  1. ChatGPT进入百度“弱智吧”后,疯了
  2. Android OpenGL ES 学习(十) – GLSurfaceView 源码解析GL线程以及自定义 EGL
  3. 家是文艺腔,更是烟火气
  4. 一道算法题:12个黑球和1个白球围成一个圆
  5. 2018淘宝违规扣分什么时候清零公告
  6. 按照jdk8时,javac不是内部或外部命令
  7. FPS之游戏绘制(六)
  8. Adobe Photoshop CS4 官方简体中文版+正版序列号+安装教程
  9. Android清空画布
  10. vue生命周期图详解,流程图