微信小程序 Canvas裁切案例

这篇具有很好参考价值的文章主要介绍了微信小程序 Canvas裁切案例。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

源于 https://ask.csdn.net/questions/7797682

效果

输入

微信小程序 Canvas裁切案例

输出

微信小程序 Canvas裁切案例

环境

基础库版本 2.20.x使用的新版的canvas(也不算新两三年了)。

知识点
  1. canvas

  2. base64转临时路径

代码

index.wxml

<canvas type="2d" id="photo" class="photo" disable-scroll="{{true}}" style="width: {{width}}rpx;height: {{height}}rpx;"></canvas>
<button type="primary" bindtap="chooseImage">选择照片</button>

index.wxss

.photo {
  margin: 80rpx auto;
  background-color: rgb(68, 48, 247);
  border: 4px solid #ddd;
}

index.js 重点

代码没有进行封装,仅仅只是方便预览

const app = getApp()

Page({
  data: {
    canvas: null,
    ctx: null,
    height: 441,
    width: 358,
  },
  onReady() {
    // 创建一个 SelectorQuery 对象,选择器选取范围为这个组件实例内
    const query = this.createSelectorQuery()
    // 选择wxml上id是photo的元素
    query.select('#photo').fields({ node: true, size: true });
    // 执行
    query.exec((res) => {
      const canvas = res[0].node // 因为返回的是数组 所以要去第一个
      const ctx = canvas.getContext('2d') // 获取画布内容 
      canvas.width = this.data.width  // 真实宽度 
      canvas.height = this.data.height  // 真实高度  
      this.data.canvas = canvas; // 暂存到data中方便其他方法调用
      this.data.ctx = ctx; // 暂存到data中方便其他方法调用
    })
  },
  chooseImage() { // 选择图片
    wx.chooseMedia({ // 选择媒体
      count: 1, // 照片数量
      mediaType: ['image'], // 图片
      sourceType: ['album'], // 相册
      success: (res) => {
        let tempFilePath = res.tempFiles[0].tempFilePath
        const canvas = this.data.canvas; // 画布 
        const ctx = this.data.ctx;
        const { width, height } = canvas; // 画布的大小
        let tempImage = canvas.createImage();
        tempImage.src = tempFilePath;
        tempImage.onload = () => {
          // fill 填充模式
          let originWidth = tempImage.width; // 原宽度
          let originHeight = tempImage.height; // 原高度
          let targetWidth = width; // 目标宽度
          let targetHeight = height; // 目标高度 
          let scale = 0; // 临时比例 
          // 当原宽度小于原高度时
          if (originWidth < originHeight) {
            // 临时比例暂存 
            scale = originWidth / originHeight;
            originWidth = targetWidth;
            originHeight = originWidth / scale;
          }
          // 非
          else {
            scale = originWidth / originHeight;
            originHeight = targetHeight;
            originWidth = originHeight * scale;
          }
          // 计算偏移量
          const offsetX = - (originWidth - targetWidth) / 2
          const offsetY = - (originHeight - targetHeight) / 2
          // 清空画布
          ctx.clearRect(0, 0, canvas.width, canvas.height)

          // 绘制图片
          ctx.drawImage(tempImage, offsetX, offsetY, originWidth, originHeight)
          const base64 = canvas.toDataURL() // canvas输出base64
          const fs = wx.getFileSystemManager(); // 获取获取全局唯一的文件管理器
          const filePath = wx.env.USER_DATA_PATH + '/tmp.png'; // 写入临时路径
          fs.writeFile({
            filePath,
            data: base64.replace(/^data:image\/\w+;base64,/, ""), // 剔除base64特有前缀
            encoding: 'base64',
            success: (res) => {
              wx.saveImageToPhotosAlbum({ // 保存到手机相册
                filePath,
                success: (res) => {
                  wx.showToast({
                    title: '保存成功',
                  })
                }
              })
            }
          });
        }
      }
    })
  }
})
源码

完整代码片段

https://developers.weixin.qq.com/s/ERW91Dma7QCP

私信的问题
Q: Camera 如何放置遮罩层?

如果想用cover-image组件,也是一样,建议使用直接使用image组件。

微信小程序 Canvas裁切案例微信小程序 Canvas裁切案例

<camera device-position="back" flash="off" binderror="error" style="width: 100%; height: 300px;">
   <image src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Finews.gtimg.com%2Fnewsapp_bt%2F0%2F13210298185%2F1000&refer=http%3A%2F%2Finews.gtimg.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1667063277&t=74fe7de947f94409ff089e9b123d87ef"></image>
</camera>
评论的问题
Q: 使用Camera组件如何套用该案例?

将canvas组件复制到页面中,把拍照返回的临时图片路径替换到选择图片回调返回的临时图片。

代码部分

index.wxml 节选

<!-- 追加到页面 -->
<canvas type="2d" id="photo" class="photo" disable-scroll="{{true}}" style="width: {{width}}rpx;height: {{height}}rpx;"></canvas>

index.js 重点

const app = getApp()

Page({
    data: {
        canvas: null,
        ctx: null,
        height: 441,
        width: 358,
    },
    onReady() {
        // 创建一个 SelectorQuery 对象,选择器选取范围为这个组件实例内
        const query = this.createSelectorQuery()
        // 选择wxml上id是photo的元素
        query.select('#photo').fields({ node: true, size: true });
        // 执行
        query.exec((res) => {
            const canvas = res[0].node // 因为返回的是数组 所以要去第一个
            const ctx = canvas.getContext('2d') // 获取画布内容 
            canvas.width = this.data.width  // 真实宽度 
            canvas.height = this.data.height  // 真实高度  
            this.data.canvas = canvas; // 暂存到data中方便其他方法调用
            this.data.ctx = ctx; // 暂存到data中方便其他方法调用
        })
    },
    onLoad() {
        this.ccc = wx.createCameraContext()
    },
    takePhoto() {
        this.ccc.takePhoto({
            quality: 'high',
            success: (res) => {
                let tempFilePath = res.tempImagePath
                const canvas = this.data.canvas; // 画布 
                const ctx = this.data.ctx;
                const { width, height } = canvas; // 画布的大小
                let tempImage = canvas.createImage();
                tempImage.src = tempFilePath;
                tempImage.onload = () => {
                    // fill 填充模式
                    let originWidth = tempImage.width; // 原宽度
                    let originHeight = tempImage.height; // 原高度
                    let targetWidth = width; // 目标宽度
                    let targetHeight = height; // 目标高度 
                    let scale = 0; // 临时比例 
                    // 当原宽度小于原高度时
                    if (originWidth < originHeight) {
                        // 临时比例暂存 
                        scale = originWidth / originHeight;
                        originWidth = targetWidth;
                        originHeight = originWidth / scale;
                    }
                    // 非
                    else {
                        scale = originWidth / originHeight;
                        originHeight = targetHeight;
                        originWidth = originHeight * scale;
                    }
                    // 计算偏移量
                    const offsetX = - (originWidth - targetWidth) / 2
                    const offsetY = - (originHeight - targetHeight) / 2
                    // 清空画布
                    ctx.clearRect(0, 0, canvas.width, canvas.height)

                    // 绘制图片
                    ctx.drawImage(tempImage, offsetX, offsetY, originWidth, originHeight)
                    const base64 = canvas.toDataURL() // canvas输出base64
                    const fs = wx.getFileSystemManager(); // 获取获取全局唯一的文件管理器
                    const filePath = wx.env.USER_DATA_PATH + '/tmp.png'; // 写入临时路径
                    fs.writeFile({
                        filePath,
                        data: base64.replace(/^data:image\/\w+;base64,/, ""), // 剔除base64特有前缀
                        encoding: 'base64',
                        success: (res) => {
                            wx.saveImageToPhotosAlbum({ // 保存到手机相册
                                filePath,
                                success: (res) => {
                                    wx.showToast({
                                        title: '保存成功',
                                    })
                                }
                            })
                        }
                    });
                }
            }
        })
    },
    error(e) {
        console.log(e.detail)
    }
})
源码

https://developers.weixin.qq.com/s/DxGSlEmD7wCu

拓展

处理图片的颜色值

index.js 节选文章来源地址https://www.toymoban.com/news/detail-487791.html

// 绘制图片
ctx.drawImage(tempImage, offsetX, offsetY, originWidth, originHeight)
// getImageData 
// 按照从左到右,从上到下的顺序去存储像素点信息
// 每四个数组元素代表了一个像素点的RGBA信息
const imageData = ctx.getImageData(0, 0, originWidth, originHeight)
// 灰度范围
const minGray = 230;
// 目标色
const white = 255;
for (let i = 0; i < imageData.data.length; i += 4) {
    let tmpRed = imageData.data[i]
    let tmpGreen = imageData.data[i + 1]
    let tmpBlue = imageData.data[i + 2]
    let tmpAlpha = imageData.data[i + 3]
    if (tmpRed > minGray && tmpGreen > minGray && tmpBlue > minGray && tmpAlpha > minGray) {
        imageData.data[i] = white;
        imageData.data[i + 1] = white;
        imageData.data[i + 2] = white;
        imageData.data[i + 3] = white;
    }
}
ctx.putImageData(imageData, 0, 0)

到了这里,关于微信小程序 Canvas裁切案例的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 微信小程序 新版canvas绘制图片方法

    截至2022.12.23 修改日 微信小程序开发文档介绍不全,导致很多用户绘制图片不显示或失败,因此写下截至目前的可行方案 如果新手不熟悉canvas,先看下小程序官方文档 可运行案例: wxml: js:

    2024年02月12日
    浏览(47)
  • 微信小程序canvas生成图片并保存

    需求: 做一个类似下图的功能。图片内容是动态的,用canvas画出来,生成临时图片,再保存。 实现:  其他使用,查看微信开发文档  

    2024年02月13日
    浏览(53)
  • 微信小程序实现canvas画圆形微信头像

    1.需要获取用户信息,拿到用户头像图片 2.实例化一个canvas对象,绘制出圆形并将头像固定到圆形中心位置 3.实现效果      

    2024年02月15日
    浏览(38)
  • 微信小程序使用canvas绘制网络图片,使用canvas将图片变成圆形

    以上的写法 会造成某些图标无法绘制上去, 解决方法是在网络图片中不断嵌套,先绘制大图片,再绘制小图片的顺序 网上说使用先下载到本地,再使用img.src加载,我尝试过还是不行 长用在海报,需要将用户的头像画到canvas图片上,如: 其原理就是在图片上面放一个圆

    2024年02月13日
    浏览(70)
  • 微信小程序canvas画布不清晰解决方法

    绘制的图片,文字等十分模糊 添加以下代码,通过设置分辨率来解决 完整代码: 模糊不清的时候 多多进行调试一下就可以了 多尝试新方案 

    2024年02月10日
    浏览(61)
  • 微信小程序--canvas画布实现图片的编辑

    上传图片,编辑图片大小,添加文字,改变文字颜色等 微信小程序--canvas画布实现图片的编辑 软件环境:微信开发者工具 官方下载地址:微信开发者工具下载地址与更新日志 | 微信开放文档 1、基本需求。 实现上传图片 实现图片编辑 实现添加文字 实现导出图片 2、案例目录

    2024年02月05日
    浏览(53)
  • uniapp 使用canvas画海报(微信小程序)

    效果展示:  项目要求:点击分享绘制海报,并实现分享到好友,朋友圈,并保存 先实现绘制海报   下面是海报下面的分享弹窗 因为分享到朋友圈实在没找到有使用自定义按钮的可能,所以还是需要点击右上角胶囊    以上就是画海报以及分享的全部过程了,另有一个点:

    2024年02月13日
    浏览(66)
  • 微信小程序:使用canvas 生成图片 并分享

    废话不多说直接上代码!!!! 最终效果图  

    2024年02月11日
    浏览(62)
  • 【微信小程序】解决canvas组件层级最高问题

    1、为什么canvas组件总是会在最上层? 因为canvas组件是由客户端创建的原生组件, 原生组件层级是最高的 ,所以页面中的其他组件无论设置 z-index 为多少都无法盖在原生组件上 。 2、如何解决canvas层级最高问题?                                                    wx

    2024年02月11日
    浏览(52)
  • 微信小程序canvas画图案列,实现生成头像并保存,小程序新版canvas变化,小程序中canvas注意事项

    你一定见过很多制作头像的小程序,无论是国庆的红旗,圣诞的帽子,还是疫情的口罩,都可以用小程序生成应景的头像,那么具体的代码是怎么实现的呢?前些天帮别人做了一个生成姓氏头像的功能,里面的实现原理基本一致,都是通过Canvas实现,以生成姓氏头像为例,记录一下小程序的

    2024年02月09日
    浏览(55)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包