zoukankan      html  css  js  c++  java
  • 微信小程序 canvas生成海报图片模糊问题

    一、制作正常显示海报,生成二倍海报隐藏 代码如下

    <!--index.wxml-->
    <view class="container">
        <view class="show">
          <image src="{{cardPath}}" alt="" class="card"></image>
          <text class="name">{{sendName}}</text>
          <image src="{{headPath}}" class="header"></image>
        </view>
        <view class="btn" bindtap="saveImage">保存图片</view>
        <view class="canvasBox" style="0;height:0;overflow: hidden;opacity:0;position:absolute;left:-750px;top:0;">
          <canvas canvas-id='myCanvas' style='750px;height:1000px;'></canvas>
        </view>
    </view>
    

      

    /*css*/
    .btn {
       300rpx;
      height: 90rpx;
      line-height: 90rpx;
      text-align: center;
      color: #fff;
      font-size: 38rpx;
      border-radius: 10rpx;
      background: #f9c22e;
    }
    /*  */
    .show{
      750rpx;
      height:1000rpx;
      background: #fff;
      border:1px solid red;
      position: relative;
    }
    .show .card{
      display: block;
      690rpx;
      height: 940rpx;
      margin:20rpx auto 0;
    }
    .show .name,.show .header{
      position: absolute;
    }
    .show .name{
      100%;
      text-align: center;
      color:red;
      top:26rpx;
    }
    .show .header{
      100rpx;
      height: 100rpx;
      border-radius: 100%;
      top:500rpx;
      left:100rpx;
    }
    

      

    二、canvas 画二倍图  文字居中  实际展示正常海报为375*470 绘制中生成图模糊(文字有锯齿边,图片模糊)。绘制过程中绘制二倍图大小750*940 并保存,则能解决该问题

    let x = ctx.width / 2;//canvas宽的一半
    //画图
      drawCanvas: function () {
        let that = this;
        let ctx = wx.createCanvasContext('myCanvas');
        let ctxW = 750;
        let ctxH = 1000;
        ctx.width = 750;
        ctx.height = 1000;
        let x = ctx.width / 2;
    
        // 垂直渐变
        const grd = ctx.createLinearGradient(0, 0, 0, ctxH);
        grd.addColorStop(0, '#ffffff');
        grd.addColorStop(1, '#ffffff');
        ctx.setFillStyle(grd);
    
        ctx.fillRect(0, 0, ctxW, ctxH);
    
        wx.getImageInfo({
          src: that.data.cardPath,
          success: (res) => {
            ctx.drawImage(res.path, 0, 0, 750, 1000); //card
            
            ctx.setFontSize(32) //字体大小
            ctx.setFillStyle('red') //字体颜色
            ctx.textAlign = "center"; //文字居中
            ctx.fillText(that.data.sendName, x, 34)
            ctx.stroke();
    
            wx.getImageInfo({
              src: that.data.headPath,
              success: (res) => {
                ctx.save();
                ctx.beginPath(); //开始绘制
                ctx.arc(150,358,50, 0, 2 * Math.PI)
                ctx.fill()
                ctx.clip(); //剪切
                ctx.drawImage(res.path,100, 308, 100, 100); //userHeader  // 推进去图片必须是https
                ctx.restore(); //恢复之前保存的绘图上下文 继续绘制
                /**/ 
                ctx.save();
                ctx.draw();
              }
            })
    
          }
        })
      },
    

      三、下载保存图片  

    // 保存图片
      saveImage: function (e) {
        wx.canvasToTempFilePath({
          x: 0, //指定的画布区域的左上角横坐标	
          y: 0, //指定的画布区域的左上角纵坐标	
           750, //指定的画布区域的宽度
          height: 940, //指定的画布区域的高度
          destWidth: 750, //输出的图片的宽度
          destHeight: 940, //输出的图片的高度
          canvasId: 'myCanvas',
          fileType: 'jpg', //图片的质量,目前仅对 jpg 有效。取值范围为 (0, 1],不在范围内时当作 1.0 处理。
          quality: 1,
          success: function (res) {
            wx.saveImageToPhotosAlbum({
              filePath: res.tempFilePath,
              success(result) {
                wx.showToast({
                  title: '图片保存成功',
                  icon: 'success',
                  duration: 2000
                })
              }
            })
          }
        })
      },
    

     结果对比:左图文字明显有锯齿,右图没有,用户头像右图更清晰。保存下来看效果更明显。

      

    tips:该文档解决两个问题

    (1)文字居中显示

    (2)生成图模糊

    (3)圆形头像绘制,另一篇文档实际上线项目中手机端头像保存为空,此版本优化。

    (4)页面加载完成绘制图形,实际项目中页面加载完成但接口数据不一定返回,所以绘图过程需在接口数据成功返回中调用,避免用户头像为空,绘图为空

    (5)优化上一版本大量无用代码,全程使用线上数据代码

    (6)canva绘制海报时可添加透明背景。

      
    // 垂直渐变
        const grd = ctx.createLinearGradient(0, 0, 0, ctxH);
        grd.addColorStop(0, 'transparent');
        grd.addColorStop(1, 'transparent');
        ctx.setFillStyle(grd);

    (7)手机端保存图片  当用户拒绝保存申请时下次点击按钮无法自动调用新的授权申请,点击按钮无反应

      此问题已解决网上有各种教程解决方法,当前随笔未更新,只记录图片模糊问题,下个随笔增加拒绝授权至重新授权过程

    -------- 注意:鉴于有网友反映该功能无效,声明更新下记录,以下附上全部代码,请测试使用

    tap1:该项目为18年开发,请选择低版本库,基础库版本太高会导致报错原因未知,但是报错不影响图片的保存;有知道原因的的兄弟姐妹可以留言回复,谢谢。

    若出现以下错误请回调基础库(注该报错依然能保存图片)

    tap2:(1)测试1:图片为百度域名下,因此需要忽略域名校验;开发工具可以保存,手机端保存空白。

    (2)测试2:使用公司域名且小程序后台已配置dowload合法域名则不需要忽略域名校验(手机端测试需使用合法域名才能进行图片的保存)

     

    tap3:此前百度地址图片没有了,打开为空,找不到图片导致保存为空

    完整代码:

    <!--index.wxml-->
    <view class="container">
        <view class="show">
          <image src="{{cardPath}}" alt="" class="card"></image>
          <text class="name">{{sendName}}</text>
          <image src="{{headPath}}" class="header"></image>
        </view>
        <view class="btn" bindtap="saveImage">保存图片</view>
        <view class="canvasBox">
          <view class="canvasBox" style="0;height:0;overflow: hidden;opacity:0;position:absolute;left:-750px;top:0;">
            <canvas canvas-id='myCanvas' style='750px;height:1000px;'></canvas>
          </view>
        </view>
    </view>
    

      

    /*css*/
    
    .btn {
       300rpx;
      height: 90rpx;
      line-height: 90rpx;
      text-align: center;
      color: #fff;
      font-size: 38rpx;
      border-radius: 10rpx;
      background: #f9c22e;
    }
    
    /*  */
    
    .show {
       750rpx;
      height: 1000rpx;
      background: #fff;
      border: 1px solid red;
      position: relative;
    }
    
    .show .card {
      display: block;
       690rpx;
      height: 940rpx;
      margin: 20rpx auto 0;
    }
    
    .show .name, .show .header {
      position: absolute;
    }
    
    .show .name {
       100%;
      text-align: center;
      color: red;
      top: 26rpx;
    }
    
    .show .header {
       100rpx;
      height: 100rpx;
      border-radius: 100%;
      top: 100rpx;
      left: 100rpx;
    }
    

      

    //index.js
    const app = getApp()
    Page({
      data: {
        cardPath: 'https://www.cnblogs.com/skins/mountainink/images/top.jpg',
        headPath: 'https://www.cnblogs.com/skins/mountainink/images/top.jpg',
        sendName: '姓名姓名姓名'
      },
      onLoad: function (options) {
        var that = this;
        that.drawCanvas();
      },
      /*画图*/
      drawCanvas: function () {
        let that = this;
        let ctx = wx.createCanvasContext('myCanvas');
        let ctxW = 750;
        let ctxH = 940;
        ctx.width = 750;
        ctx.height = 940;
        let x = ctx.width / 2;
    
        // 垂直渐变
        const grd = ctx.createLinearGradient(0, 0, 0, ctxH);
        grd.addColorStop(0, '#ffffff');
        grd.addColorStop(1, '#ffffff');
        ctx.setFillStyle(grd);
    
        ctx.fillRect(0, 0, ctxW, ctxH);
    
        wx.getImageInfo({
          src: that.data.cardPath,
          success: (res) => {
            ctx.drawImage(res.path, 0, 0, 750, 940); //card
            
            ctx.setFontSize(32) //字体大小
            ctx.setFillStyle('red') //字体颜色
            ctx.textAlign = "center"; //文字居中
            ctx.fillText(that.data.sendName, x, 34)
            ctx.stroke();
    
            wx.getImageInfo({
              src: that.data.headPath,
              success: (res) => {
                ctx.save();
                ctx.beginPath(); //开始绘制
                ctx.arc(150,358,50, 0, 2 * Math.PI)
                ctx.fill()
                ctx.clip(); //剪切
                ctx.drawImage(res.path,100, 308, 100, 100); //userHeader  // 推进去图片必须是https
                ctx.restore(); //恢复之前保存的绘图上下文 继续绘制
                /**/ 
                ctx.save();
                ctx.draw();
              }
            })
    
          }
        })
      },
      /* 保存图片 */
      saveImage: function (e) {
        wx.canvasToTempFilePath({
          x: 0, //指定的画布区域的左上角横坐标	
          y: 0, //指定的画布区域的左上角纵坐标	
           750, //指定的画布区域的宽度
          height: 940, //指定的画布区域的高度
          destWidth: 750, //输出的图片的宽度 
          destHeight: 940, //输出的图片的高度
          canvasId: 'myCanvas',
          fileType: 'jpg', //图片的质量,目前仅对 jpg 有效。取值范围为 (0, 1],不在范围内时当作 1.0 处理。
          quality: 1,
          success: function (res) {
            wx.saveImageToPhotosAlbum({
              filePath: res.tempFilePath,
              success(result) {
                wx.showToast({
                  title: '图片保存成功',
                  icon: 'success',
                  duration: 2000
                })
              }
            })
          }
        })
      },
      
    })
    

      以下appid使用xxxx代码,请使用自己的appid,不是自己的appid没有权限登陆。

    {
    	"description": "项目配置文件。",
    	"packOptions": {
    		"ignore": []
    	},
    	"setting": {
    		"urlCheck": false,
    		"es6": true,
    		"enhance": false,
    		"postcss": true,
    		"preloadBackgroundData": false,
    		"minified": true,
    		"newFeature": true,
    		"coverView": true,
    		"nodeModules": false,
    		"autoAudits": false,
    		"showShadowRootInWxmlPanel": true,
    		"scopeDataCheck": false,
    		"uglifyFileName": false,
    		"checkInvalidKey": true,
    		"checkSiteMap": true,
    		"uploadWithSourceMap": true,
    		"compileHotReLoad": false,
    		"babelSetting": {
    			"ignore": [],
    			"disablePlugins": [],
    			"outputPath": ""
    		},
    		"useIsolateContext": true,
    		"useCompilerModule": false,
    		"userConfirmedUseCompilerModuleSwitch": false
    	},
    	"compileType": "miniprogram",
    	"libVersion": "2.15.0",
    	"appid": "XXXXXX",
    	"projectname": "canvas",
    	"isGameTourist": false,
    	"simulatorType": "wechat",
    	"simulatorPluginLibVersion": {},
    	"condition": {
    		"search": {
    			"current": -1,
    			"list": []
    		},
    		"conversation": {
    			"current": -1,
    			"list": []
    		},
    		"game": {
    			"currentL": -1,
    			"list": []
    		},
    		"miniprogram": {
    			"current": -1,
    			"list": []
    		}
    	}
    }
    

      

  • 相关阅读:
    Python 音视频方面资源大全
    MD5( 信息摘要算法)的概念原理及python代码的实现
    base64编解码学习及python代码实现
    操作系统下cache的几个概念
    scp 跨机远程拷贝
    VIM -小技巧汇总
    python中的进制转换
    linux目录跳转快捷方式——z武器
    ubuntu 16.04 清空log文件的方法
    【linux】crontab失效
  • 原文地址:https://www.cnblogs.com/cdj61/p/11050557.html
Copyright © 2011-2022 走看看