Canvas:掌握颜色线条与图像文字设置
想象一下,用几行代码就能创造出如此逼真的图像和动画,仿佛将艺术与科技完美融合,前端开发的Canvas技术正是这个数字化时代中最具魔力的一环,它不仅仅是网页的一部分,更是一个无限创意的画布,一个让你的想象力自由驰骋的平台。
目录
颜色样式设置
线条样式设置
图像样式设置
文字样式设置
颜色样式设置
设置基础样式:除了绘制简单的图形,填充线条的样式外,我们还可以给图形进行一个上色处理,对颜色样式进行一个简单的设置,如果我们可以设置一下线条的颜色:
<body><canvas id="canvas" width="600" height="400"></canvas><script>let canvas = document.getElementById("canvas"); // 获取2维画笔,上下文对象let ctx = canvas.getContext("2d");let heartPath = new Path2D();// 初始起点heartPath.moveTo(300, 200)heartPath.bezierCurveTo(350, 150, 400, 200, 300, 300); heartPath.bezierCurveTo(200, 200, 250, 150, 300, 200); // 设置线条为红色,支持16进制,rgb(a) 等格式ctx.strokeStyle='red';ctx.stroke(heartPath)let chatPath = new Path2D();chatPath.moveTo(200, 300)chatPath.quadraticCurveTo(150, 300, 150, 200); chatPath.quadraticCurveTo(150, 100, 300, 100); chatPath.quadraticCurveTo(450, 100, 450, 200); chatPath.quadraticCurveTo(450, 300, 250, 300); chatPath.quadraticCurveTo(250, 350, 150, 350); chatPath.quadraticCurveTo(200, 350, 200, 300); ctx.strokeStyle='blue';ctx.stroke(chatPath)</script>
</body>
得到的效果如下所示:

设置渐变样式:如果想设置渐变的样式的话,可以通过调用createLinearGradient函数创建
1)线性渐变:后添加在0-1之间的某个数值点位上设置颜色,从开始坐标到结束坐标进行颜色样式的渐变效果展示,代码示例如下:
<body><canvas id="canvas" width="600" height="400"></canvas><script>let canvas = document.getElementById("canvas"); // 获取2维画笔,上下文对象let ctx = canvas.getContext("2d");// 绘制矩形let linearGradient = ctx.createLinearGradient(100, 200, 400, 500); // 创建线性渐变linearGradient.addColorStop(0, "red"); // 添加颜色 从第一个坐标开始linearGradient.addColorStop(0.5, "yellow"); // 添加颜色 从中间开始linearGradient.addColorStop(1, "blue"); // 添加颜色 从最后一个坐标结束ctx.fillStyle = linearGradient; // 设置填充样式ctx.fillRect(100, 200, 300, 300);</script>
</body>
最终得到的结果如下所示:

当然如果想看到渐变效果动态的变化,没问题,这里我们设置一下渲染函数,动态的改变某一位置的颜色渐变效果,示例代码如下:
<body><canvas id="canvas" width="600" height="400"></canvas><script>let canvas = document.getElementById("canvas"); // 获取2维画笔,上下文对象let ctx = canvas.getContext("2d");let index = 0;function render() {// 把上一次的绘制结果清除ctx.clearRect(0, 0, 600, 400);index += 0.01if (index > 1) {index = 0;}let linearGradient = ctx.createLinearGradient(100, 200, 400, 500); // 创建线性渐变linearGradient.addColorStop(0, "red"); // 添加颜色 从第一个坐标开始linearGradient.addColorStop(index, "#008c8c"); // 添加颜色 从中间开始linearGradient.addColorStop(1, "blue"); // 添加颜色 从最后一个坐标结束ctx.fillStyle = linearGradient; // 设置填充样式ctx.fillRect(100, 200, 300, 300);requestAnimationFrame(render);}requestAnimationFrame(render);</script>
</body>
最终呈现的效果如下所示:

2)镜像渐变:如果想创建镜像渐变的话,可以通过两个坐标表示内外圆,然后设置渐变效果,示例代码如下:
<body><canvas id="canvas" width="600" height="400"></canvas><script>let canvas = document.getElementById("canvas"); // 获取2维画笔,上下文对象let ctx = canvas.getContext("2d");// 绘制圆/*参数依次是 (x0, y0, r0, x1, y1, r1),表示两个圆之间的渐变。在这里:(300, 200, 0) 表示内圆的中心坐标 (x0, y0) 是 (300, 200),半径 r0 是 0,即一个点。(300, 200, 100) 表示外圆的中心坐标 (x1, y1) 是 (300, 200),半径 r1 是 100。*/let radiaGradient = ctx.createRadialGradient(300, 200, 0, 300, 200, 100);radiaGradient.addColorStop(0, 'red');radiaGradient.addColorStop(0.3, '#ffcccc');radiaGradient.addColorStop(1, 'blue');ctx.fillStyle = radiaGradient;ctx.fillRect(0, 0, 600, 400);</script>
</body>
最终呈现的效果如下所示:

当然这里我们可以通过设置俩个球心,实现一个3d地球的效果,示例代码如下:
<body><canvas id="canvas" width="600" height="400"></canvas><script>let canvas = document.getElementById("canvas"); // 获取2维画笔,上下文对象let ctx = canvas.getContext("2d");// 绘制圆let radiaGradient = ctx.createRadialGradient(250, 150, 10, 300, 200, 100);radiaGradient.addColorStop(0, '#fff');radiaGradient.addColorStop(1, 'blue');ctx.fillStyle = radiaGradient;ctx.arc(300, 200, 100, 0, Math.PI * 2); // 绘制圆ctx.fill() // 填充</script>
</body>
最终呈现的效果如下:

3)圆锥渐变:如果想实现圆锥渐变的话,可以使用createConicGradient函数进行操作,示例代码如下:
<body><canvas id="canvas" width="600" height="400"></canvas><script>let canvas = document.getElementById("canvas"); // 获取2维画笔,上下文对象let ctx = canvas.getContext("2d");// 绘制扇形渐变let coneGradient = ctx.createConicGradient(0, 300, 200);coneGradient.addColorStop(0, 'red');coneGradient.addColorStop(1, 'blue');ctx.fillStyle = coneGradient;ctx.fillRect(0, 0, 600, 400) // 填充</script>
</body>
最终呈现的效果如下所示:

线条样式设置
在上面我们讲解到了canvas的颜色样式的设置,那么如果我们想对canvas的线条进行一个样式的修改应该如何操作呢?这里开始进行一个简单的讲述,给出如下场景的修改线条样式的函数:
lineWidth = value:设置线条宽度。代码如下:
<body><canvas id="canvas" width="600" height="400"></canvas><script>let canvas = document.getElementById("canvas"); // 获取2维画笔,上下文对象let ctx = canvas.getContext("2d");// 设置线条function draw() {for (let i = 0; i < 10; i++) {ctx.lineWidth = i + 1;ctx.beginPath(); // 开始一条新路径ctx.moveTo(5+i*14, 5); // 移动到起点ctx.lineTo(5+i*14, 140) // 绘制一条到终点ctx.stroke();}}draw();</script>
</body>
线宽是指给定路径的中心到两边的粗细。换句话说就是在路径的两边各绘制线宽的一半,因为画布的坐标并不和像素直接对应,当需要获得精确的水平或垂直线的时候要特别注意。

lineCap = type:设置线条末端样式。代码如下:
<body><canvas id="canvas" width="600" height="400"></canvas><script>let canvas = document.getElementById("canvas");// 获取2维画笔,上下文对象let ctx = canvas.getContext("2d");// 设置线条function draw() {var lineCap = ['butt', 'round', 'square'];// 创建路径ctx.strokeStyle = '#09f';ctx.beginPath();ctx.moveTo(10, 10);ctx.lineTo(140, 10);ctx.moveTo(10, 140);ctx.lineTo(140, 140);ctx.stroke();// 画线条ctx.strokeStyle = 'black';for (var i = 0; i < lineCap.length; i++) {ctx.lineWidth = 15;ctx.lineCap = lineCap[i];ctx.beginPath();ctx.moveTo(25 + i * 50, 10);ctx.lineTo(25 + i * 50, 140);ctx.stroke();}}draw();</script>
</body>
这里绘制了三条直线,分别赋予不同的 lineCap 值,还有两条辅助线,为了可以看得更清楚它们之间的区别,三条线的起点终点都落在辅助线上。最左边的线用了默认的 butt 。可以注意到它是与辅助线齐平的。中间的是 round 的效果,端点处加上了半径为一半线宽的半圆。右边的是 square 的效果,端点处加上了等宽且高度为一半线宽的方块:

lineJoin = type:设置线条与线条间接接合处的样式。代码如下:
<body><canvas id="canvas" width="600" height="400"></canvas><script>let canvas = document.getElementById("canvas");// 获取2维画笔,上下文对象let ctx = canvas.getContext("2d");// 设置线条function draw() {var lineJoin = ['round', 'bevel', 'miter'];ctx.lineWidth = 10;for (var i = 0; i < lineJoin.length; i++) {ctx.lineJoin = lineJoin[i];ctx.beginPath();ctx.moveTo(-5, 5 + i * 40);ctx.lineTo(35, 45 + i * 40);ctx.lineTo(75, 5 + i * 40);ctx.lineTo(115, 45 + i * 40);ctx.lineTo(155, 5 + i * 40);ctx.stroke();}}draw();</script>
</body>
这里用三条折线来做例子,分别设置不同的 lineJoin 值。最上面一条是 round 的效果,边角处被磨圆了,圆的半径等于线宽。中间和最下面一条分别是 bevel 和 miter 的效果。当值是 miter 的时候,线段会在连接处外侧延伸直至交于一点:

setLineDash(segments):设置当前虚线样式。代码如下:
<body><canvas id="canvas" width="600" height="400"></canvas><script>let canvas = document.getElementById("canvas");// 获取2维画笔,上下文对象let ctx = canvas.getContext("2d");// 设置线条ctx.moveTo(150, 150)ctx.lineTo(300, 200)ctx.lineTo(450, 150)// 设置虚线ctx.setLineDash([10, 20])ctx.stroke()</script>
</body>
setLineDash 方法接受一个数组,来指定线段与间隙的交替:

lineDashOffset = value:设置当前虚线样式的起始偏移量。
<body><canvas id="canvas" width="600" height="400"></canvas><script>let canvas = document.getElementById("canvas");// 获取2维画笔,上下文对象let ctx = canvas.getContext("2d");// 设置线条let index = 0function render() {ctx.clearRect(0, 0, 600, 400);index++if (index > 40) {index = 0}ctx.moveTo(150, 150)ctx.lineTo(300, 200)ctx.lineTo(450, 150)// 设置虚线ctx.setLineDash([40, 20])// 设置偏移量ctx.lineDashOffset = indexctx.stroke()requestAnimationFrame(render) // 动画渲染}render()</script>
</body>
设置线条的移动:

shadowOffsetX、shadowOffsetY、shadowBlur、shadowColor:设置阴影。代码如下:
<body><canvas id="canvas" width="600" height="400"></canvas><script>let canvas = document.getElementById("canvas");// 获取2维画笔,上下文对象let ctx = canvas.getContext("2d");// 设置线条let index = 0function render() {ctx.clearRect(0, 0, 600, 400);index++if (index > 40) {index = 0}ctx.moveTo(150, 150)ctx.lineTo(300, 200)ctx.lineTo(450, 150)// 设置阴影ctx.shadowOffsetX = 10 // 阴影偏移量ctx.shadowOffsetY = 10 // 阴影偏移量ctx.shadowBlur = 5 // 阴影模糊度ctx.shadowColor = "rgba(255, 100, 10, 1)" // 阴影颜色// 设置虚线ctx.setLineDash([40, 20])// 设置偏移量ctx.lineDashOffset = indexctx.stroke()requestAnimationFrame(render) // 动画渲染}render()</script>
</body>
效果如下:

图像样式设置
canvas更有意思的一项特性就是图像操作能力,可以用于动态的图像合成或者作为图形的背景,以及游戏界面(Sprites)等等。浏览器支持的任意格式的外部图片都可以使用,比如 PNG、GIF 或者JPEG,你甚至可以将同一个页面中其他 canvas 元素生成的图片作为图片源。
patterns图案填充:在上面我们讲解到了对画面进行一个颜色的填充,把画面填充成某一个固定的颜色或者说是一个渐变的颜色,那如果我想填充的不是渐变的颜色,而是一个个图像呢?这里我们就需要借助patterns这个属性来实现了,如下给出示例代码:
<body><canvas id="canvas" width="600" height="400"></canvas><script>let canvas = document.getElementById("canvas"); // 获取2维画笔,上下文对象let ctx = canvas.getContext("2d");// 创建图案样式let img = new Image();img.src = "./1.jpg"// 加载图片img.onload = function(){// 创建图案对象 createPattern(图片对象, 重复方式)let pattern = ctx.createPattern(img, "repeat");ctx.fillStyle = pattern;ctx.fillRect(0, 0, 600, 400);}</script>
</body>
最终呈现的效果如下所示:

drawImage:对图片进行缩放,裁剪操作:
<body><canvas id="canvas" width="600" height="400"></canvas><script>let canvas = document.getElementById("canvas"); // 获取2维画笔,上下文对象let ctx = canvas.getContext("2d");// 创建图案样式let img = new Image();img.src = "./1.jpg"// 加载图片img.onload = function(){// 第一种绘制图片方式:参数是:图片资源,以及水平和垂直位置// ctx.drawImage(img, 0, 0) // 第二种绘制图片方式:参数是:图片资源,以及水平和垂直位置,以及缩放宽高600和400// ctx.drawImage(img, 0, 0, 600, 400) // 第三种绘制图片方式:参数是:图片资源,以及裁剪的起点位置和矩形宽高,以及裁剪以及水平和垂直位置,以及缩放宽高600和400ctx.drawImage(img, 1040, 100, 1500, 720, 0, 0, 600, 400) }</script>
</body>
最终呈现的效果如下所示:

当然drawImage函数也是可以对视频进行相应操作的,这里简单赘述一下,示例代码如下:
<body><canvas id="canvas" width="600" height="400"></canvas><video src="./1.mp4" controls style="width: 400px; height: auto;" hidden></video><button id="btn">播放 / 暂停</button><script>let canvas = document.getElementById("canvas"); // 获取2维画笔,上下文对象let ctx = canvas.getContext("2d");// 设置图像视频let video = document.querySelector("video");video.src = "./1.mp4";let btn = document.getElementById("btn");btn.onclick = function () {if (video.paused) {video.play();render();} else {video.pause();}}// 添加logolet img = new Image();img.src = "./1.jpg";// 渲染函数function render() {ctx.drawImage(video, 0, 0, 600, 400); // 绘制视频ctx.drawImage(img, 500, 350, 100, 50); // 绘制logorequestAnimationFrame(render);}</script>
</body>
效果如下:

文字样式设置
canvas提供了两种方法来渲染文本,这里做一个简单的介绍,如下:
fillText(text, x, y [, maxWidth]):在指定的 (x,y) 位置填充指定的文本,绘制的最大宽度是可选的。代码如下:
<body><canvas id="canvas" width="600" height="400"></canvas><script>let canvas = document.getElementById("canvas"); // 获取2维画笔,上下文对象let ctx = canvas.getContext("2d");// 设置文字ctx.font = "30px Arial";// 设置填充渲染文字ctx.fillText("Hello World", 10, 30);</script>
</body>

strokeText(text, x, y [, maxWidth]):在指定的 (x,y) 位置绘制文本边框,绘制的最大宽度是可选的。代码如下:
<body><canvas id="canvas" width="600" height="400"></canvas><script>let canvas = document.getElementById("canvas"); // 获取2维画笔,上下文对象let ctx = canvas.getContext("2d");// 设置文字ctx.font = "30px Arial";// 设置文字颜色ctx.strokeStyle='red';// 设置文本对齐方式, 默认是 leftctx.textAlign = "center";// 设置基线对齐方式, 默认是 topctx.textBaseline = "middle";// 设置文本方向,默认是 ltrctx.direction = "rtl";// 设置填充渲染文字ctx.strokeText("Hello World!", 300, 200);</script>
</body>
上面代码同时给出了常用的文字操作方式,这里做一个简单的举例,最终得到的效果如下:

相关文章:
Canvas:掌握颜色线条与图像文字设置
想象一下,用几行代码就能创造出如此逼真的图像和动画,仿佛将艺术与科技完美融合,前端开发的Canvas技术正是这个数字化时代中最具魔力的一环,它不仅仅是网页的一部分,更是一个无限创意的画布,一个让你的想象…...
打包导入pyzbar的脚本时的注意事项
目录 前言问题问题的出现解决 总结 本文由Jzwalliser原创,发布在CSDN平台上,遵循CC 4.0 BY-SA协议。 因此,若需转载/引用本文,请注明作者并附原文链接,且禁止删除/修改本段文字。 违者必究,谢谢配合。 个人…...
02-android studio实现下拉列表+单选框+年月日功能
一、下拉列表功能 1.效果图 2.实现过程 1)添加组件 <LinearLayoutandroid:layout_width"match_parent"android:layout_height"wrap_content"android:layout_marginLeft"20dp"android:layout_marginRight"20dp"android…...
曹操的五色棋布阵 - 工厂方法模式
定场诗 “兵无常势,水无常形,能因敌变化而取胜者,谓之神。” 在三国的战场上,兵法如棋,布阵如画。曹操的五色棋布阵,不正是今日软件设计中工厂方法模式的绝妙写照吗?让我们从这个神奇的布阵之…...
谷粒商城学习笔记-逆向工程错误记录
文章目录 1,Since Maven 3.8.1 http repositories are blocked.1.1 在maven的settings.xml文件中,新增如下配置:1.2,执行clean命令刷新maven配置 2,internal java compiler error3,启动逆向工程报错&#x…...
FastAPI+SQLAlchemy数据库连接
FastAPISQLAlchemy数据库连接 目录 FastAPISQLAlchemy数据库连接配置数据库连接创建表模型创建alembic迁移文件安装初始化编辑env.py编辑alembic.ini迁移数据库 视图函数查询 配置数据库连接 # db.py from sqlalchemy import create_engine from sqlalchemy.orm import sessio…...
Android中的适配器,你知道是做什么的吗?
😄作者简介: 小曾同学.com,一个致力于测试开发的博主⛽️,主要职责:测试开发、CI/CD,日常还会涉及Android开发工作。 如果文章知识点有错误的地方,还请大家指正,让我们一起学习,一起…...
GitHub详解:代码托管与协作开发平台
文章目录 一、GitHub简介二、GitHub的核心功能2.1 仓库(Repository)2.2 版本控制与分支(Branch)2.3 Pull Request2.4 Issues与Projects2.5 GitHub Actions 三、GitHub的使用方法3.1 注册与登录3.2 创建和管理仓库3.3 使用Git进行代…...
【植物大战僵尸杂交版】获取+存档插件
文章目录 一、还记得《植物大战僵尸》吗?二、在哪下载,怎么安装?三、杂交版如何进行存档功能概述 一、还记得《植物大战僵尸》吗? 最近,一款曾经在15年前风靡一时的经典游戏《植物大战僵尸》似乎迎来了它的"文艺复…...
BP神经网络与反向传播算法在深度学习中的应用
BP神经网络与反向传播算法在深度学习中的应用 在神经网络的发展历史中,BP神经网络(Backpropagation Neural Network)占有重要地位。BP神经网络通过反向传播算法进行训练,这种算法在神经网络中引入了一种高效的学习方式。随着深度…...
【数据结构与算法】插入排序
💓 博客主页:倔强的石头的CSDN主页 📝Gitee主页:倔强的石头的gitee主页 ⏩ 文章专栏:《数据结构与算法》 期待您的关注 ...
MySQL如何实现数据排序
根据explain的执行计划来看,MySQL可以分为索引排序和filesort 索引排序 如果查询中的order by字句包含的字段已经在索引中,且索引的排列顺序和order by子句一致,则可直接利用索引进行排序,由于索引有序,所以排序效率…...
给我的 IM 系统加上监控两件套:【Prometheus + Grafana】
监控是一个系统必不可少的组成部分,实时,准确的监控,将会大大有助于我们排查问题。而当今微服务系统的话有一个监控组合很火那就是 Prometheus Grafana,嘿你别说 这俩兄弟配合的相当完美,Prometheus负责数据采集&…...
【Python】基于动态规划和K聚类的彩色图片压缩算法
引言 当想要压缩一张彩色图像时,彩色图像通常由数百万个颜色值组成,每个颜色值都由红、绿、蓝三个分量组成。因此,如果我们直接对图像的每个像素进行编码,会导致非常大的数据量。为了减少数据量,我们可以尝试减少颜色…...
【做一道算一道】和为 K 的子数组
给你一个整数数组 nums 和一个整数 k ,请你统计并返回 该数组中和为 k 的子数组的个数 。 子数组是数组中元素的连续非空序列。 示例 1: 输入:nums [1,1,1], k 2 输出:2 示例 2: 输入:nums [1,2,3],…...
Facebook应用开发:认证与授权登录流程详解
Facebook作为全球最大的社交平台之一,提供了强大的认证与授权机制,允许第三方应用通过Facebook登录来简化用户的注册和登录流程。本文将详细介绍Facebook应用开发中的认证和授权登录流程,以及如何在应用中实现这一功能。 关键词 Facebook登…...
实战:搭建一款属于自己的个人知识库~docusaurus(强大且丝滑)-2024.7.7(测试成功)
目录 文章目录 目录docusaurus简介效果专题链接👏环境源码1、安装基础环境2、拉取代码3、安装坚果云并同步md核心文件4、构建运行5、配置脚本环境1.配置vscode终端到ecs的免密2.配置win10 vscode终端环境变量 6、构建并推送静态文件到ecs关于我最后最后 docusaurus简…...
Java教程之IO模式精讲,NIO+BIO
第一章 BIO、NIO、AIO介绍 背景 在java的软件设计开发中,通信架构是不可避免的,我们在进行不同系统或者不同进程之间的数据交互,或 者在高并发下的通信场景下都需要用到网络通信相关的技术,对于一些经验丰富的程序员来说&#x…...
如何让代码兼容 Python 2 和 Python 3?Future 库助你一臂之力
目录 01Future 是什么? 为什么选择 Future? 安装与配置 02Future 的基本用法 1、兼容 print 函数 2、兼容整数除法 3、兼容 Unicode 字符串 03Future 的高级功能 1. 处理字符串与字节 2. 统一异常处理…...
AI让大龄程序员重新焕发活力
AI是在帮助开发者还是取代他们? 在软件开发领域,生成式人工智能(AIGC)正在改变开发者的工作方式。无论是代码生成、错误检测还是自动化测试,AI工具正在成为开发者的得力助手。然而,这也引发了对开发者职业…...
Spring Boot 实现流式响应(兼容 2.7.x)
在实际开发中,我们可能会遇到一些流式数据处理的场景,比如接收来自上游接口的 Server-Sent Events(SSE) 或 流式 JSON 内容,并将其原样中转给前端页面或客户端。这种情况下,传统的 RestTemplate 缓存机制会…...
Docker 运行 Kafka 带 SASL 认证教程
Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明:server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中,新增了一个本地验证码接口 /code,使用函数式路由(RouterFunction)和 Hutool 的 Circle…...
排序算法总结(C++)
目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指:同样大小的样本 **(同样大小的数据)**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...
Web中间件--tomcat学习
Web中间件–tomcat Java虚拟机详解 什么是JAVA虚拟机 Java虚拟机是一个抽象的计算机,它可以执行Java字节码。Java虚拟机是Java平台的一部分,Java平台由Java语言、Java API和Java虚拟机组成。Java虚拟机的主要作用是将Java字节码转换为机器代码&#x…...
React从基础入门到高级实战:React 实战项目 - 项目五:微前端与模块化架构
React 实战项目:微前端与模块化架构 欢迎来到 React 开发教程专栏 的第 30 篇!在前 29 篇文章中,我们从 React 的基础概念逐步深入到高级技巧,涵盖了组件设计、状态管理、路由配置、性能优化和企业级应用等核心内容。这一次&…...
针对药品仓库的效期管理问题,如何利用WMS系统“破局”
案例: 某医药分销企业,主要经营各类药品的批发与零售。由于药品的特殊性,效期管理至关重要,但该企业一直面临效期问题的困扰。在未使用WMS系统之前,其药品入库、存储、出库等环节的效期管理主要依赖人工记录与检查。库…...
rm视觉学习1-自瞄部分
首先先感谢中南大学的开源,提供了很全面的思路,减少了很多基础性的开发研究 我看的阅读的是中南大学FYT战队开源视觉代码 链接:https://github.com/CSU-FYT-Vision/FYT2024_vision.git 1.框架: 代码框架结构:readme有…...
Appium下载安装配置保姆教程(图文详解)
目录 一、Appium软件介绍 1.特点 2.工作原理 3.应用场景 二、环境准备 安装 Node.js 安装 Appium 安装 JDK 安装 Android SDK 安装Python及依赖包 三、安装教程 1.Node.js安装 1.1.下载Node 1.2.安装程序 1.3.配置npm仓储和缓存 1.4. 配置环境 1.5.测试Node.j…...
算法250609 高精度
加法 #include<stdio.h> #include<iostream> #include<string.h> #include<math.h> #include<algorithm> using namespace std; char input1[205]; char input2[205]; int main(){while(scanf("%s%s",input1,input2)!EOF){int a[205]…...
