uni-app微信小程序canvas中使用canvasToTempFilePath在手机上导出图片尺寸与实际不符

问题描述:比如图片的尺寸是1125*2001像素,这样用微信开发者工具下载下来的图片尺寸是1125*2001像素,用不同的手机去操作,下载出来的图片尺寸都不一样,和原图片尺寸差距很大。

解决方案:canvas写入的时候是按照当前设备像素比(pixelRatio)进行设置的,像素比pixelRatio=物理像素/设备独立像素(dips)

像素比pixelRatio=物理像素/设备独立像素(dips)

ctx.drawImage(图片对象, 图像裁剪的x位置, 图像裁剪的y位置, 裁剪的宽度, 裁剪的高度, x位置, y位置, 宽度, 高度

我这台机器的设备像素比=3,分辨率是:1920*1080 以x轴为例,这里的物理像素=1920,得出设备独立像素=1920/3=640,而canvas这里设置的大小是设备独立像素,所以576的物理像素对应到设备独立像素就是=576/3=192,

微信小程序提供了wx.getSystemInfo获取设备信息,其中pixelRatio就是设备像素比.

canvas写入的时候是按照当前设备像素比(pixelRatio)进行设置的

<button class="btn-link save-link" plain="true" @click="getCanvas">
保存图片
</button>    
<!--  canvas保存图片  -->
<canvas class="share-canvas" canvas-id="canvas" :style="canvasStyle"></canvas>
  data() {
    return {
      posterImg: {
        url: 'https://picsum.photos/1125/2001?random=1',
        width: '1125rpx',
        height: '2001rpx'
      }
    }
  },
computed: {
    canvasStyle() {
      return `width: ${this.posterImg.width}px; height:${this.posterImg.height}px;`
    }
},
methods: {
    getCanvas() {
      uni.showLoading({
        title: '保存中' // 加载转圈显示
      })
      const ctx = uni.createCanvasContext('canvas', this)
      const that = this
      // 获取背景海报详细信息
      uni.getImageInfo({
        src: that.swiper2List[that.current].image,
        success: function(res) {
          // 微信小程序提供了wx.getSystemInfo获取设备信息,其中pixelRatio就是设备像素比
          wx.getSystemInfo({
            success: function(data) {
              // canvas写入的时候是按照当前设备像素比(pixelRatio)进行设置的
              const pixelRatio = data.pixelRatio
              that.posterImg.width = res.width / pixelRatio
              that.posterImg.height = res.height / pixelRatio
              // 绘制背景海报
              ctx.drawImage(res.path, 0, 0, that.posterImg.width, that.posterImg.height)
              that.saveCanvas()
            }
          })
        }
      })
    },
    // 保存canvas为图片
    saveCanvas() {
      const _this = this
      setTimeout(() => {
        uni.canvasToTempFilePath({
          canvasId: 'canvas',
          quality: 1,
          success(result) {
            // 保存在本地
            uni.saveImageToPhotosAlbum({
              filePath: result.tempFilePath,
              success: function() {
                uni.hideLoading()
                uni.showToast({
                  title: '保存成功',
                  icon: 'success',
                  duration: 2000
                })
                console.log('save success')
              },
              fail: () => {
                uni.hideLoading()
                _this.setData({
                  flag: false
                })
              }
            })
          },
          fail: () => {
            uni.hideLoading()
            // 重复请求一次
            _this.saveCanvas()
          }
        })
      }, 200)
    }
  }
### 实现 uni-app 中的全屏截图功能 在 uni-app 开发框架中,可以利用 `canvas` 组件来实现全屏截图的功能。以下是详细的说明和代码示例: #### 原理概述 通过将页面的内容绘制到 `<canvas>` 上,再导出图片的方式完成截图操作。此过程涉及以下几个核心步骤: 1. 创建并配置 `<canvas>` 元素。 2. 使用 `drawCanvas` 方法将页面内容渲染至画布上。 3. 调用 `canvasToTempFilePath` API 将画布转换为临时文件路径。 --- #### 代码实现 以下是一个完整的全屏截图功能的实现案例: ```html <template> <view class="content"> <!-- 页面内容 --> <scroll-view scroll-y style="height: 100vh;"> <view id="screenshot-area" style="width: 100%; height: auto;"> <image src="/static/logo.png" mode="aspectFit"></image> <text>这是一个测试文字</text> </view> </scroll-view> <!-- 截图按钮 --> <button @click="takeScreenshot">点击进行全屏截图</button> <!-- 展示截图结果 --> <image v-if="screenshotPath" :src="screenshotPath" mode="widthFix"></image> </view> </template> <script> export default { data() { return { screenshotPath: '', // 存储截图后的图片路径 }; }, methods: { takeScreenshot() { const query = uni.createSelectorQuery().in(this); // 获取需要截图区域的信息 query.select('#screenshot-area').boundingClientRect(rect => { if (!rect) { console.error('无法获取截图区域'); return; } // 创建 canvas 并设置尺寸 const ctx = uni.createCanvasContext('screenshot-canvas', this); ctx.setFillStyle('#fff'); // 设置背景颜色 ctx.fillRect(0, 0, rect.width, rect.height); // 将页面内容绘制到 canvas 上 setTimeout(() => { // 确保 DOM 渲染完成后执行 ctx.draw(false, () => { // 导出 canvas 图片 uni.canvasToTempFilePath({ canvasId: 'screenshot-canvas', success: (res) => { this.screenshotPath = res.tempFilePath; // 更新截图路径 }, fail: (err) => { console.error('截图失败:', err); } }, this); }); }, 50); // 添加延迟以确保渲染完成 }).exec(); } } }; </script> <style scoped> .content { display: flex; flex-direction: column; align-items: center; } #screenshot-area { padding: 20px; } </style> ``` --- #### 关键点解析 1. **选择器查询 (`createSelectorQuery`)** - 利用 `uni.createSelectorQuery()` 查询指定节点的位置、大小等信息[^1]。 2. **Canvas 的创建绘图** - 使用 `uni.createCanvasContext(canvasId)` 初始化 Canvas 对象,并调用其方法绘制图形或填充背景[^2]。 3. **保存为图片** - 调用 `uni.canvasToTempFilePath` 将 Canvas 内容转存为本地临时文件路径。 --- #### 注意事项 - 若目标设备不支持某些特性(如 Web 端),需提前做好兼容性处理。 - 在复杂布局下可能需要调整样式以适配不同屏幕分辨率。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值