文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

聊聊生成水印原理与插件编写

2024-12-03 03:20

关注

一 前言

今天分享一个小程序生成水印的小技巧——canvas绘制背景图,接下来我会详细介绍绘制的细节。希望开发过微信小程序的同学可以把文章收藏起来,这样如果以后遇到类似的需求,可以翻出来作为参考。

本文的插件同样适用于Taro,uniapp,原生等构建的小程序项目,项目demo是采用Taro-Vue构建的。

我们先来看看demo效果。

二 原理实现

canvas绘制背景图这个方案原理本质上是非常简单的,就如把大象放冰箱一共分成三步那样简单????。

那么问题来了,我们绘制的底图是整张水印底图吗?

答案是否定的。我们只需要画一个模版图片就可以了,如下图所示:

但是为了让水印填充整个手机屏幕,我们需要将水印图片作为背景图片,然后设置background-repeat:repeat;就可以了。

三 细节实现

demo样板

canvas模版接下来我们开始实现具体的细节,首先我们页面放入一个

  1. <view 
  2.     class="markBox" 
  3.     :style="{ backgroundImage: `url(${url})` }" 
  4. >   
  5.     
  6.       v-show="isShow" 
  7.       :id="settings.id" 
  8.       type="2d" 
  9.       :class="settings.id" 
  10.       :style="{ width:settings.width + 'px' , height : settings.height + 'px' }" 
  11.     /> 
  12. view

 

  1. 这里有一点值得注意,就是我们设置的type = '2d'最好不要用canvasId方式来操作canvas,包括获取canvas实例,调用canvasToTempFilePathapi等,不然可能会失效。这里采用的是通过id方式,来获取canvas实例的。
  2. 当我们绘制完成后,隐藏canvas,将view容器设置背景图片,背景图片就是canvas绘制形成的图片。
  3. canvas宽度和高度是根据canvas的配置项添加的,所以我们要动态用style属性设置宽高。

配置项

  1. export default { 
  2.     
  3.    name:"MakeWaterMark"
  4.    data(){ 
  5.        return { 
  6.            isShow:true
  7.            url:''
  8.            settings: { 
  9.                 'id''waterMark',                   
  10.                 'content''我不是外星人',             
  11.                 'width': 200,                        
  12.                 'height': 200,                        
  13.                 'rotate': -45,                        
  14.                 'left':60,                           
  15.                 'top':80,                            
  16.                 'fontSize''15px',                  
  17.                 'fontFamily''Microsoft JhengHei',  
  18.                 'bg''#fff',                         
  19.                 'color''#ccc',                     
  20.                 'fontWeight''normal',              
  21.             } 
  22.        } 
  23.    }, 

样式处理

  1. .markBox{ 
  2.     position: fixed; 
  3.     left:0; 
  4.     right:0; 
  5.     bottom: 0; 
  6.     top:0; 
  7.     background-repeat:repeat ; 

插件核心代码

插件的核心功能就是生成水印图片,除此之外还要满足两个要求:

接下来我们看一下具体细节:

  1. function createPromise(callback){ 
  2.     return new Promise((resolve,reject)=>{ 
  3.         callback(resolve,reject) 
  4.     }) 
  5.  
  6.  
  7. class MarkwaterMark{ 
  8.     constructor(options){ 
  9.          
  10.        this.platform  = null  
  11.        this.pixelRatio = null 
  12.        this.context = null 
  13.        this.options = options  
  14.        this.ready = createPromise(this._init.bind(this))    
  15.         
  16.        this.make = (cb) => {  
  17.           if(this.context){ 
  18.              this._markPicture(cb) 
  19.           }else
  20.               this.ready.then(()=>{ 
  21.                  this.context && this._markPicture(cb) 
  22.               }) 
  23.           }     
  24.        } 
  25.     } 
  26.      
  27.     _init(next,fail){ 
  28.        const { platform , pixelRatio } = wx.getSystemInfoSync() 
  29.        this.platform = platform 
  30.        this.pixelRatio = pixelRatio 
  31.        const query = wx.createSelectorQuery() 
  32.        query.select('#' + this.options.id ).fields({ 
  33.         node: true
  34.         sizetrue 
  35.       }).exec((res)=>{ 
  36.         let { 
  37.             node, 
  38.         } = res[0] || {}  
  39.         if (!node) return fail && fail() 
  40.         this.context = node.getContext('2d')     
  41.         this.node = node 
  42.         next() 
  43.       }) 
  44.     } 
  45.      
  46.     _markPicture(cb){ 
  47.        const { width , height , bg ,color ,fontSize, fontFamily,fontWeight ,content , lefttop ,rotate } = this.options 
  48.        this.node.width = (width || 200) * this.pixelRatio 
  49.        this.node.height =( height || 200) * this.pixelRatio 
  50.        this.context.scale(this.pixelRatio,this.pixelRatio) 
  51.        this.context.fillStyle = bg || '#fff' 
  52.        this.context.fillRect(0, 0, width, height) 
  53.        this.context.fillStyle = color || '#000' 
  54.        this.context.save() 
  55.        this.context.translate(left,top
  56.        this.context.rotate(Math.PI * rotate / 180 ) 
  57.        this.context.font =  `${fontWeight} 400 ${fontSize} ${fontFamily}` 
  58.        this.context.fillText(content, 0, 0) 
  59.        this.context.restore()  
  60.        this._savePicture(cb) 
  61.     } 
  62.      
  63.     _savePicture(cb){ 
  64.      const { width , height  } = this.options 
  65.        wx.canvasToTempFilePath({ 
  66.           x:0, 
  67.           y:0, 
  68.           width, 
  69.           height, 
  70.           destWidth:width*1, 
  71.           destHeight:height*1, 
  72.           canvas:this.node, 
  73.           success:function(res){ 
  74.              cb && cb(res.tempFilePath) 
  75.           } 
  76.        }) 
  77.     } 
  78.  
  79. function makeWatermark(options){ 
  80.   if(!wx) return null 
  81.   return new MarkwaterMark(options)  
  82.  
  83. module.exports = makeWatermark 

核心功能流程分析:

插件使用

在业务组件(上述demo)中,我们就可以使用上述插件了。具体参考如下:

  1. mounted(){  
  2.       Taro.nextTick(()=>{ 
  3.            
  4.           const marker = makeWatermark(this.settings) 
  5.            
  6.           marker.make((url)=>{ 
  7.                
  8.               const fileManage = Taro.getFileSystemManager() 
  9.               let base64 = 'data:image/jpg;base64,' + fileManage.readFileSync(url,'base64'); 
  10.               this.url = base64 
  11.               this.isShow  = false 
  12.           }) 
  13.       }) 
  14.   }, 

重要细节:

这里还有一个比较重要细节就是,小程序中背景图片一般都是网络图片或者base64图片,对于临时路径的图片在真机上是不显示的。为了解决这个问题,我们需要把临时图片转换成base64格式图片。

效果:

大功告成!!!

四 总结

 

通过本文我们学习了微信小程序生成水印的方式和流程。还有一些开发中的细节问题。感兴趣的同学可以收藏起来,以备不时之需。

 

来源: 前端Sharing内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯