uniapp 微信小程序自定义分享图片

场景:微信小程序用户,点击小程序里商品的分享按钮时,想要不同的商品展示不用的分享内容,比如分享图片上展示商品的图片、价格等信息。分享的UI图如下: 

 

实现方法:

1. 分享按钮:<button open-type="share">onShareAppMessage(OBJECT)

2. 自定义内容:因为onShareAppMessage的imageUrl参数的支持的是本地文件路径、代码包文件路径或者网络图片路径 ,所以这里实现自定义的分享的方法是结合canvas画布uni.createCanvasContext(canvasId, this),将画好的内容利用uni.canvasToTempFilePath(object, component)导出生成指定大小的图片,再将返回的文件路径赋值给imageUrl,即可实现。

 具体可看官网:分享 | uni-app官网 、uni.createCanvasContext(canvasId, this) | uni-app官网、uni-app官网、uni.canvasToTempFilePath(object, component) | uni-app官网

代码:先贴上画布的代码,这里画了三种自定义分享的内容,样式在代码下方。

1. 新建一个组件文件:ShareCanvas.vue

<template>
  <view class="ShareCanvas">
    <view class="canvas">
      <canvas canvas-id="shareCanvas" />
    </view>
  </view>
</template>

<script>
export default {
  name: 'ShareCanvas',
  methods: {
    // 订单分享
    setOrderCanvas(info) {
      return new Promise(async (resolve, reject) => {
        console.log('订单分享-info', info);
        try {
          const ctx = uni.createCanvasContext('shareCanvas', this)
          // 绘制背景图
          ctx.setFillStyle('#19C161')
          ctx.fillRect(0, 0, 211, 170) // 保证宽高比是 5:4

          // 绘制文本信息
          ctx.setFontSize(21);
          ctx.setTextAlign('left')
          ctx.setFillStyle('#FFFFFF')
          ctx.fillText('我买好啦!', 9, 32)

          // 浅绿色背景
          this.setRadius(ctx, 10, 106, 11, 97, 27) // 加圆角
          ctx.setFillStyle('#EFF9F1')
          ctx.fill()
          // ctx.fillRect(106, 11, 97, 27) // x, y, width, height

          ctx.setFontSize(14);
          ctx.setTextAlign('center')
          ctx.setFillStyle('#19C161')
          ctx.fillText('跟团号:' + info.followNum, 155, 30)

          this.setRadius(ctx, 3, 9, 49, 194, 106)
          ctx.setFillStyle('#FFFFFF')
          ctx.fill()
          // ctx.fillRect(9, 49, 194, 106) // 不设置圆角的时候这么画有背景色的矩形

          // 画商品图
          ctx.save();
          this.setRadius(ctx, 5, 17, 59, 85, 85)
          ctx.clip();//画了圆 再剪切 原始画布中剪切任意形状和尺寸。一旦剪切了某个区域,则所有之后的绘图都会被限制在被剪切的区域内
          try {
            const { path } = await this.getImge(info.orderCartInfos[0].productImg)
            ctx.drawImage(path, 17, 59, 85, 85)
          } catch (error) {
            console.error(error);
          }
          ctx.restore();

          if (info.teamLeaderUser && info.teamLeaderUser.avatar) {
            // 团长头像
            ctx.save();
            this.setRadius(ctx, 5, 110, 60, 25, 25)
            ctx.clip(); // 画了圆 再剪切 原始画布中剪切任意形状和尺寸。一旦剪切了某个区域,则所有之后的绘图都会被限制在被剪切的区域内
            try {
              const { path } = await this.getImge(info.teamLeaderUser.avatar)
              ctx.drawImage(path, 110, 60, 25, 25)
            } catch (error) {
              console.error(error);
            }
            ctx.restore();
          }

          if (info.teamLeaderUser && info.teamLeaderUser.nickname) {
            // 团长昵称
            ctx.setFontSize(12);
            ctx.setTextAlign('left')
            ctx.setFillStyle('#96999B')
            ctx.fillText(info.teamLeaderUser.nickname.length > 4 ? info.teamLeaderUser.nickname.slice(0, 4) + '...' : info.teamLeaderUser.nickname, 140, 76)
          }

          ctx.setFontSize(14);
          ctx.setTextAlign('center')
          ctx.setFillStyle('#FB7415')
          ctx.fillText(`¥${info.orderCartInfos[0].unitPrice}`, 152, 105)

          this.setRadius(ctx, 10, 115, 118, 75, 26)

          const grd = ctx.createLinearGradient(115, 118, 115, 144)
          grd.addColorStop(0, '#FDAC2F')
          grd.addColorStop(0.5, '#FDA72C')
          grd.addColorStop(1, '#FB5615')

          // 橙色按钮背景
          ctx.setFillStyle(grd)
          // ctx.fillRect(230/2, 218/2, 149/2, 53/2) // x, y, width, height
          ctx.fill()

          ctx.setFontSize(12);
          ctx.setTextAlign('center')
          ctx.setFillStyle('#FFFFFF')
          ctx.fillText('去看看 >', 152, 135)

          ctx.draw(false, (() => {
            setTimeout(() => {
              uni.canvasToTempFilePath({
                canvasId: 'shareCanvas',
                success: (res) => {
                  return resolve(res.tempFilePath)
                },
                fail: function (error) {
                  console.log('fail----fail', error);
                  //TODO
                  return reject(error)
                }
              }, this)
            }, 500);
          }))
        } catch (error) {
          console.log('画图失败error', error);
          return reject(error)
        }
      })
    },
    // 商品分享
    setGoodsShareCanvas(info) {
      console.log('商品分享--info', info);
      return new Promise(async (resolve, reject) => {
        try {
          const ctx = uni.createCanvasContext('shareCanvas', this)
          // 绘制背景图
          ctx.setFillStyle('#FFFFFF')
          ctx.fillRect(0, 0, 211, 170)

          // 团长头像
          ctx.save();
          this.setRadius(ctx, 5, 0, 0, 30, 30)
          ctx.clip(); // 画了圆 再剪切 原始画布中剪切任意形状和尺寸。一旦剪切了某个区域,则所有之后的绘图都会被限制在被剪切的区域内
          try {
            const { path } = await this.getImge(info.avatar)
            ctx.drawImage(path, 0, 0, 30, 30)
          } catch (error) {
            console.error(error);
          }
          ctx.restore();

          // 团长昵称
          ctx.setFontSize(12);
          ctx.setTextAlign('left')
          ctx.setFillStyle('#96999B')
          ctx.fillText(info.nickname.length > 11 ? info.nickname.slice(0, 11) + `${info.pinkId ? '...的团' : '...'}` : info.nickname + '的团', 35, 18)

          // 商品1图
          ctx.save();
          this.setRadius(ctx, 3, 0, 35, 211, 211)
          ctx.clip(); // 画了圆 再剪切 原始画布中剪切任意形状和尺寸。一旦剪切了某个区域,则所有之后的绘图都会被限制在被剪切的区域内
          try {
            const { path } = await this.getImge(info.image)
            ctx.drawImage(path, 0, 35, 211, 211)
          } catch (error) {
            console.error(error);
          }
          ctx.restore();

          // 绿色背景
          ctx.setFillStyle('#19C161')
          ctx.fillRect(0, 130, 131, 40) // x, y, width, height

          ctx.setFontSize(16);
          ctx.setTextAlign('center')
          ctx.setFillStyle('#FFFFFF')
          ctx.fillText(`¥${info.pinkId ? info.pinkPrice : info.price}起`, 65, 130 + 18)

          ctx.setFontSize(12);
          ctx.setTextAlign('center')
          ctx.setFillStyle('#FFFFFF')
          ctx.fillText(`¥${info.otPrice}`, 65, 130 + 34)

          // 划线
          ctx.beginPath()
          ctx.setLineWidth(1);
          ctx.setStrokeStyle('#FFFFFF')
          ctx.moveTo(40, 130 + 30)
          ctx.lineTo(90, 130 + 30)
          ctx.stroke()

          // 深绿色背景
          ctx.setFillStyle('#19AF5C')
          ctx.fillRect(131, 130, 211 - 131, 40)

          if (info.pinkId) {
            // 立即跟团按钮
            ctx.setFontSize(16);
            ctx.setTextAlign('center')
            ctx.setFillStyle('#FFFFFF')
            ctx.fillText(`立即跟团`, 131 + (211 - 131) / 2, 130 + 26)
          } else {
            // 已团数量
            ctx.setFontSize(12);
            ctx.setTextAlign('center')
            ctx.setFillStyle('#FFFFFF')
            ctx.fillText(`已团 ${this.getSales(info.sales)} 件`, 131 + (211 - 131) / 2, 130 + 25)
          }

          ctx.draw(false, (() => {
            uni.canvasToTempFilePath({
              canvasId: 'shareCanvas',
              success: (res) => {
                return resolve(res.tempFilePath)
              },
              fail: function (error) {
                console.log('fail----fail', error);
                //TODO
                return reject(error)
              }
            }, this)
          }))
        } catch (error) {
          uni.hideLoading()
          console.log('画图失败error', error);
          return reject(error)
        }
      })
    },
    // 团分享
    setGroupShareCanvas(info) {
      console.log('团分享-info', info);
      return new Promise(async (resolve, reject) => {
        try {
          const ctx = uni.createCanvasContext('shareCanvas', this)
          // 绘制背景图
          ctx.setFillStyle('#FFFFFF')
          ctx.fillRect(0, 0, 211, 170)

          if (info.productImageList.length == 1) {
            // 团长头像
            ctx.save();
            this.setRadius(ctx, 5, 0, 0, 30, 30)
            ctx.clip(); // 画了圆 再剪切 原始画布中剪切任意形状和尺寸。一旦剪切了某个区域,则所有之后的绘图都会被限制在被剪切的区域内
            try {
              const { path } = await this.getImge(info.avatar)
              ctx.drawImage(path, 0, 0, 30, 30)
            } catch (error) {
              console.error(error);
            }
            ctx.restore();

            // 团长昵称
            ctx.setFontSize(12);
            ctx.setTextAlign('left')
            ctx.setFillStyle('#96999B')
            ctx.fillText((info.nickname.length > 11 ? info.nickname.slice(0, 11) + '...' : info.nickname) + '的团', 35, 18)

            // 商品1图
            ctx.save();
            this.setRadius(ctx, 3, 0, 35, 211, 211)
            ctx.clip(); // 画了圆 再剪切 原始画布中剪切任意形状和尺寸。一旦剪切了某个区域,则所有之后的绘图都会被限制在被剪切的区域内
            try {
              const { path } = await this.getImge(info.productImageList[0])
              ctx.drawImage(path, 0, 35, 211, 211)
            } catch (error) {
              console.error(error);
            }
            ctx.restore();
          }

          if (info.productImageList.length >= 2) {
            // 团长头像
            ctx.save();
            this.setRadius(ctx, 5, 0, 0, 42, 42)
            ctx.clip(); // 画了圆 再剪切 原始画布中剪切任意形状和尺寸。一旦剪切了某个区域,则所有之后的绘图都会被限制在被剪切的区域内
            try {
              const { path } = await this.getImge(info.avatar)
              ctx.drawImage(path, 0, 0, 42, 42)
            } catch (error) {
              console.error(error);
            }
            ctx.restore();

            // 团长昵称
            ctx.setFontSize(12);
            ctx.setTextAlign('left')
            ctx.setFillStyle('#96999B')
            ctx.fillText((info.nickname.length > 10 ? info.nickname.slice(0, 10) + '...' : info.nickname) + '的团', 47, 25)

            // 商品1图
            ctx.save();
            this.setRadius(ctx, 3, 0, 51, 69, 69)
            ctx.clip(); // 画了圆 再剪切 原始画布中剪切任意形状和尺寸。一旦剪切了某个区域,则所有之后的绘图都会被限制在被剪切的区域内
            try {
              const { path } = await this.getImge(info.productImageList[0])
              ctx.drawImage(path, 0, 51, 69, 69)
            } catch (error) {
              console.error(error);
            }
            ctx.restore();

            // 商品2图
            ctx.save();
            this.setRadius(ctx, 3, 69 + 2, 51, 69, 69)
            ctx.clip(); // 画了圆 再剪切 原始画布中剪切任意形状和尺寸。一旦剪切了某个区域,则所有之后的绘图都会被限制在被剪切的区域内
            try {
              const { path } = await this.getImge(info.productImageList[1])
              ctx.drawImage(path, 69 + 2, 51, 69, 69)
            } catch (error) {
              console.error(error);
            }
            ctx.restore();

            if (info.productImageList.length >= 3) {
              // 商品3图
              ctx.save();
              this.setRadius(ctx, 3, 69 * 2 + 4, 51, 69, 69)
              ctx.clip(); // 画了圆 再剪切 原始画布中剪切任意形状和尺寸。一旦剪切了某个区域,则所有之后的绘图都会被限制在被剪切的区域内
              try {
                const { path } = await this.getImge(info.productImageList[2])
                ctx.drawImage(path, 69 * 2 + 4, 51, 69, 69)
              } catch (error) {
                console.error(error);
              }
              ctx.restore();
            }
          }

          // 绿色背景
          ctx.setFillStyle('#19C161')
          ctx.fillRect(0, 128, 211, 42) // x, y, width, height

          ctx.setFontSize(16);
          ctx.setTextAlign('center')
          ctx.setFillStyle('#FFFFFF')
          ctx.fillText(`立即跟团`, 211 / 2, 128 + 26)

          ctx.draw(false, (() => {
            uni.canvasToTempFilePath({
              canvasId: 'shareCanvas',
              success: (res) => {
                return resolve(res.tempFilePath)
              },
              fail: function (error) {
                console.log('fail----fail', error);
                //TODO
                return reject(error)
              }
            }, this)
          }))
        } catch (error) {
          console.log('画图失败error', error);
          return reject(error)
        }
      })
    },
    /**
     * 设置圆角矩形
     *
     * @param ctx 绘图上下文
     * @param cornerRadius 圆角半径
     * @param width 矩形宽度
     * @param height 矩形高度
     * @param x 矩形左上角的 x 坐标
     * @param y 矩形左上角的 y 坐标
     * @returns 无返回值
     */
    setRadius(ctx, cornerRadius, x, y, width, height) {
      // 开始绘制路径
      ctx.beginPath();
      // 绘制最左侧的圆角
      ctx.arc(x + cornerRadius, y + cornerRadius, cornerRadius, Math.PI, Math.PI * 1.5);
      // 绘制顶部边缘
      ctx.moveTo(x + cornerRadius, y);
      ctx.lineTo(x + width - cornerRadius, y);
      ctx.lineTo(x + width, y + cornerRadius);
      // 绘制最右侧的圆角
      ctx.arc(x + width - cornerRadius, y + cornerRadius, cornerRadius, Math.PI * 1.5, Math.PI * 2);
      // 绘制右侧边缘
      ctx.lineTo(x + width, y + height - cornerRadius);
      ctx.lineTo(x + width - cornerRadius, y + height);
      // 绘制最下侧的圆角
      ctx.arc(x + width - cornerRadius, y + height - cornerRadius, cornerRadius, 0, Math.PI * 0.5);
      // 绘制底部边缘
      ctx.lineTo(x + cornerRadius, y + height);
      ctx.lineTo(x, y + height - cornerRadius);
      // 绘制最左侧的圆角
      ctx.arc(x + cornerRadius, y + height - cornerRadius, cornerRadius, Math.PI * 0.5, Math.PI);
      // 绘制左侧边缘
      ctx.lineTo(x, y + cornerRadius);
      ctx.lineTo(x + cornerRadius, y);
      // 闭合路径
      ctx.closePath();
    },
    // 获取图片地址
    getImge(path) {
      // 利用promise异步转同步,否则可能显示不了~
      return new Promise((resolve, reject) => {
        uni.getImageInfo({
          src: path,
          success: function (res) {
            if (res && res.path) {
              resolve(res)
            } else {
              reject(false)
            }
          },
          fail: function (res) {
            reject(res)
          }
        })
      })
    },
    getSales(sales) {
      return sales >= 10000 ? sales / 10000 + 'w+' : sales
    },
  }
}
</script>

<style lang="scss" scoped>
// 隐藏画布
.ShareCanvas {
  position: absolute;
  top: -200px;
  z-index: -1;
  opacity: 0;
  .canvas canvas {
    width: 211px;
    height: 170px; // +16
  }
}
</style>

2. 在分享按钮的页面使用这个画布组件。

onShareAppMessage 方法的内容:

注意:

  1. onShareAppMessage 方法要和 onLoad 等生命周期函数同级
  2. 因为里面画布生成图片是异步的,我在上面用Promise处理了,这里需要async await接收~
async onShareAppMessage(res) {
    const { id, title, avatar, nickname, productDetailList } = this.detailInfo
    if (res.target && res.target.id) { // 分享商品
      console.log('分享商品');
      const item = productDetailList.find(p => p.id == res.target.id) || {}
      try {
        uni.showLoading({ title: '分享信息生成中', mask: true })
        const imageUrl = await this.$refs.ShareCanvas.setGoodsShareCanvas({ ...item, avatar, nickname, pinkId: id }) // 用不同的画布画样式,就调对应的方法名,注意里面需要的参数要传对
        uni.hideLoading()
        return {
          title: item.storeName || '好物多多,快来选购啦~',
          path: '/pages/home/index', // 这里是你的分享里面的跳转地址
          imageUrl: imageUrl || ''
        }
      } catch (error) {
        uni.hideLoading()
      }
    } else {
      // 分享团
      console.log('分享团', productDetailList);
      try {
        uni.showLoading({ title: '分享信息生成中', mask: true })
        const productImageList = productDetailList.map(item => item.image)
        const imageUrl = await this.$refs.ShareCanvas.setGroupShareCanvas({ avatar, nickname, productImageList }) // 用不同的画布画样式,就调对应的方法名,注意里面需要的参数要传对
        uni.hideLoading()
        return {
          title: title || '好物多多,快来选购啦~',
          path: '/pages/home/index', // 这里是你的分享里面的跳转地址
          imageUrl: imageUrl || ''
        }
      } catch (error) {
        uni.hideLoading()
      }
    }
  },

setOrderCanvas()方法的样式 

 

setGoodsShareCanvas()方法的样式

setGroupShareCanvas()方法的样式

画画的时候,要是找不准xy的位置,可以从这三种样式里选一个样式接近的再慢慢修改~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/725687.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Mysten Labs宣布推出Walrus:一种去中心化存储和数据可用性协议

Walrus是为区块链应用和自主代理提供的创新去中心化存储网络。Walrus存储系统今天以开发者预览版的形式发布&#xff0c;面向Sui开发者征求反馈意见&#xff0c;并预计很快会向其他Web3社区广泛推广。 通过采用纠删编码创新技术&#xff0c;Walrus能够快速且稳健地将非结构化数…

Day10—Spark SQL基础

Spark SQL介绍 ​ Spark SQL是一个用于结构化数据处理的Spark组件。所谓结构化数据&#xff0c;是指具有Schema信息的数据&#xff0c;例如JSON、Parquet、Avro、CSV格式的数据。与基础的Spark RDD API不同&#xff0c;Spark SQL提供了对结构化数据的查询和计算接口。 Spark …

人工智能指数报告

2024人工智能指数报告&#xff08;一&#xff09;&#xff1a;研发 前言 全面分析人工智能的发展现状。 从2017年开始&#xff0c;斯坦福大学人工智能研究所&#xff08;HAI&#xff09;每年都会发布一份人工智能的研究报告&#xff0c;人工智能指数报告&#xff08;AII&…

网络安全:入侵检测系统的原理与应用

文章目录 网络安全&#xff1a;入侵检测系统的原理与应用引言入侵检测系统简介IDS的工作原理IDS的重要性结语 网络安全&#xff1a;入侵检测系统的原理与应用 引言 在我们的网络安全系列文章中&#xff0c;我们已经涵盖了从SQL注入到端点保护的多个主题。本篇文章将探讨入侵检…

Apple - Authorization Services Programming Guide

本文翻译整理自&#xff1a;Authorization Services Programming Guide&#xff08;更新日期&#xff1a;2011-10-19 https://developer.apple.com/library/archive/documentation/Security/Conceptual/authorization_concepts/01introduction/introduction.html#//apple_ref/d…

探究布局模型:从LayoutLM到LayoutLMv2与LayoutXLM

LAYOUT LM 联合建模文档的layout信息和text信息&#xff0c; 预训练 文档理解模型。 模型架构 使用BERT作为backbone&#xff0c; 加入2-D绝对位置信息&#xff0c;图像信息 &#xff0c;分别捕获token在文档中的相对位置以及字体、文字方向、颜色等视觉信息。 2D位置嵌入 …

天地图 uniapp使用笔记

官网地址&#xff1a;天地图API 效果&#xff1a; <template><view><!-- 显示地图的DOM节点 --><view id"container" class"content"></view><!-- END --><!-- 数据显示 --><h3>城市名称(IP属地)&#x…

rollup学习笔记

一直使用的webpack,最近突然想了解下rollup,就花点时间学习下. 一,什么是rollup? rollup 是一个 JavaScript 模块打包器&#xff0c;可以将小块代码编译成大块复杂的代码,比如我们的es6模块化代码,它就可以进行tree shaking,将无用代码进行清除,打包出精简可运行的代码包. 业…

[Linux] 系统管理

全局配置文件 用户个性化配置 配置文件的种类 alias命令和unalias命令 进程管理 进程表

AI视频智能监管赋能城市管理:打造安全有序的城市环境

一、方案背景 随着城市化进程的加速和科技的飞速发展&#xff0c;街道治安问题日益凸显&#xff0c;治安监控成为维护社会稳定和保障人民安全的重要手段。当前&#xff0c;许多城市已经建立了较为完善的治安监控体系&#xff0c;但仍存在一些问题。例如&#xff0c;监控设备分…

基于PHP的奶茶商城系统

有需要请加文章底部Q哦 可远程调试 基于PHP的奶茶商城系统 一 介绍 此奶茶商城系统基于原生PHP开发&#xff0c;数据库mysql&#xff0c;ajax实现数据交换。系统角色分为用户和管理员。系统在原有基础上添加了糖度的选择。 技术栈 phpmysqlajaxphpstudyvscode 二 功能 用户…

深入了解RTMP推流技术:视频汇聚EasyCVR低延迟与高稳定性分析

RTMP&#xff08;Real Time Messaging Protocol&#xff09;视频推流技术&#xff0c;作为音视频传输领域的关键技术之一&#xff0c;已经在直播、视频会议、在线教育等多个场景中得到了广泛应用。RTMP以其独特的优势&#xff0c;为实时音视频传输提供了高效、稳定的解决方案。…

前端框架中的路由(Routing)和前端导航(Front-End Navigation)

聚沙成塔每天进步一点点 本文回顾 ⭐ 专栏简介前端框架中的路由&#xff08;Routing&#xff09;和前端导航&#xff08;Front-End Navigation&#xff09;1. 路由&#xff08;Routing&#xff09;1.1 定义1.2 路由的核心概念1.2.1 路由表&#xff08;Route Table&#xff09;1…

Renesas MCU之IO应用介绍

目录 概述 1 软硬件环境 1.1 软件版本信息 1.2 硬件接口介绍 2 FSP配置项目 2.1 项目参数配置 2.2 生成项目框架 3 IO OutPut功能 3.1 IO输出功能实现 3.2 IO输出功能测试代码 4 IO InPut功能 4.1 IO Input功能实现 4.2 测试代码实现 5 测试结果 概述 本文主要…

springboot应用cpu飙升的原因排除

1、通过top或者jps命令查到是那个java进程&#xff0c; top可以看全局那个进程耗cpu&#xff0c;而jps则默认是java最耗cpu的&#xff0c;比如找到进程是196 1.1 top (推荐)或者jps命令均可 2、根据第一步获取的进程号&#xff0c;查询进程里那个线程最占用cpu&#xff0c;发…

Redis的缓存击穿与解决

缓存击穿问题也叫热点Key问题&#xff0c;就是一个被高并发访问并且缓存重建业务较复杂的Key突然失效了&#xff0c;无数的请求访问会在瞬间给数据库带来巨大的冲击。 Redis实战篇 | Kyles Blog (cyborg2077.github.io) 目录 解决方案 互斥锁 实现 逻辑过期 实现 解决方案…

FFmpeg开发笔记(三十九)给Visual Studio的C++工程集成FFmpeg

《FFmpeg开发实战&#xff1a;从零基础到短视频上线》一书的“第11章 FFmpeg的桌面开发”介绍了如何在Windows环境对Qt结合FFmpeg实现桌面程序&#xff0c;那么Windows系统通过Visual Studio开发桌面程序也是很常见的&#xff0c;下面就介绍如何在Visual Studio的C工程中集成F…

Day13—大语言模型

定义 大语言模型&#xff08;Large Language Models&#xff09;是一种基于深度学习的自然语言处理&#xff08;NLP&#xff09;模型&#xff0c;用于处理和生成人类语言文本。 一、认识NLP 什么是NLP ​ NLP&#xff08;Natural Language Processing&#xff09;&#xff0…

Word2Vec基本实践

系列文章目录 提示&#xff1a;这里可以添加系列文章的所有文章的目录&#xff0c;目录需要自己手动添加 例如&#xff1a;第一章 Python 机器学习入门之pandas的使用 提示&#xff1a;写完文章后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目…

西木科技Westwood-Robotics人型机器人Bruce配置和真机配置

西木科技Westwood-Robotics人型机器人Bruce配置和真机配置 本文内容机器人介绍Bruce机器人Gazebo中仿真代码部署Bruce真机代码部署 本文内容 人形机器人Brcue相关介绍docker中安装Gazebo并使用Bruce机器人控制器更换环境配置 机器人介绍 公司&#xff1a;西木科技Westwood-R…