webgl canvas系列——快速加背景、抠图、加水印并下载图片

文章目录

    • ⭐前言
    • ⭐canvas绘制图片
      • 💖绘制csdn图片
      • 💖给png图片加背景
      • 💖cavans下载图片
      • 💖cavans上传图片并抠图
      • 💖cavans添加文字水印
      • 💖inscode 完整代码块
    • ⭐结束

yma16-logo

⭐前言

大家好,我是yma16,本文分享webgl canvas系列——快速抠图、加水印。
该系列往期文章
web canvas系列——快速入门上手绘制二维空间点、线、面

⭐canvas绘制图片

方法作用
drawImage(image, x, y)image 是 image 或者 canvas 对象,x 和 y 是其在目标 canvas 里的起始坐标。
drawImage(image, x, y, width, height)width 和 height,这两个参数用来控制 当向 canvas 画入时应该缩放的大小

💖绘制csdn图片

绘制csdn图片
csdn-img
js使用drawImage绘制图片

function drawImg() {const canvas = document.getElementById("tutorial");if (canvas.getContext) {const ctx = canvas.getContext("2d");const img = new Image();img.onload = function () {ctx.drawImage(img, 0, 0);};img.src = "/src/assets/csdn.png";}else {console.log('不支持canvas')}
}window.onload = () => {drawImg()
}

csdn-draw

💖给png图片加背景

js先填充cavans背景在画图

function drawImg() {const canvas = document.getElementById("tutorial");if (canvas.getContext) {const ctx = canvas.getContext("2d");// backgroundctx.fillStyle = 'rgba(0, 0, 200, 0.5)';ctx.globalAlpha = 1ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height)const img = new Image();img.onload = function () {ctx.drawImage(img, 35, 0);};img.src = "/src/assets/csdn.png";}else {console.log('不支持canvas')}
}window.onload = () => {drawImg()
}

效果
png+background

💖cavans下载图片

方法作用
canvas.toDataURL(type, encoderOptions);HTMLCanvasElement.toDataURL() 方法返回一个包含图片展示的 data URI。可以使用 type 参数指定其类型,默认为 PNG 格式。图片的分辨率为 96dpi
  • 如果画布的高度或宽度是 0,那么会返回字符串“data:,”。
  • 如果传入的类型非“image/png”,但是返回的值以“data:image/png”开头,那么该传入的类型是不支持的。 Chrome
  • 支持“image/webp”类型。

使用toDataURL属性下载

function downloadImage(dataURL, filename) {// 创建一个a元素,用于触发下载var link = document.createElement('a');link.download = filename;link.href = dataURL;link.click();
}window.onload = () => {document.getElementById('down-btn').addEventListener('click', function () {const imgData = document.getElementById('tutorial').toDataURL("image/png");downloadImage(imgData, 'canvas图片')})
}

下载成功的效果效果
down-btn

💖cavans上传图片并抠图

前期的准备
html原生上传图片 并使用canvas绘制图片
html结构

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><link href="style.css" rel="stylesheet" type="text/css" /><title>canvas_调试</title>
</head><body><div class="title">canvas</div><div><label for="avatar">选择图片上传:</label><br><input type="file" id="avatar" name="avatar" accept="image/png, image/jpeg" /><div id="preview-img"></div></div><div class="container"><canvas id="tutorial" width="250" height="100">current stock price: $3.15 +0.15</canvas></div><div><button id="clear-back">自动抠图</button></div><br><div><button id="down-btn">下载图片</button></div><script src="script.js"></script>
</body></html>

js逻辑

const config = {cavansDom: null,uploadImgData: null,
}function InitCanvas() {const canvas = document.getElementById("tutorial");config.cavansDom = canvasif (canvas.getContext) {const ctx = canvas.getContext("2d");// backgroundctx.fillStyle = 'rgba(0, 0, 200, 0.5)';ctx.globalAlpha = 1ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height)const img = new Image();img.onload = function () {ctx.drawImage(img, 35, 0);};img.src = "/src/assets/csdn.png";}else {console.log('不支持canvas')}
}function drawImg(){canvas=config.cavansDom if (canvas.getContext) {const ctx = canvas.getContext("2d");const img = new Image();img.onload = function () {const width=img.widthconst height=img.heightcanvas.width=widthcanvas.height=heightctx.drawImage(img, 0, 0);};img.src = config.uploadImgDataconsole.log('img.src',img.src)}else {console.log('不支持canvas')}
}function downloadImage(dataURL, filename) {// 创建一个a元素,用于触发下载var link = document.createElement('a');link.download = filename;link.href = dataURL;link.click();
}function initUploadImg() {const input = document.getElementById('avatar')input.addEventListener('change', function (e) {console.log('e')const curFiles = input.files;console.log('curFiles', curFiles)config.uploadImgData = URL.createObjectURL(curFiles[0]);drawImg()})
}function initDown() {document.getElementById('down-btn').addEventListener('click', function () {const imgData = config.cavansDom.toDataURL("image/png");downloadImage(imgData, 'canvas图片')})
}
// 抠图
function clearColor(){}window.onload = () => {InitCanvas()initDown()initUploadImg()
}

效果:实现了图片的上传并使用canvas适配绘制图片
上传csdn的个人头像upload-canvas
抠图逻辑:
为了实现抠图效果,可以使用绘图上下文的globalCompositeOperation属性来控制绘制的方式。其中,source-in和source-out是实现抠图的两种常用方式。

  • 使用source-in时,绘图上下文会根据Canvas上已有的内容和新绘制的图像的像素进行合并,只保留二者重叠的部分。通过调整绘图上下文的globalAlpha属性,可以实现抠图的透明效果。

  • 使用source-out时,绘图上下文会根据Canvas上已有的内容和新绘制的图像的像素进行合并,只保留二者不重叠的部分。同样,可以通过调整绘图上下文的globalAlpha属性,实现抠图的透明效果。

source-in效果

// 抠图
function clearColor(){document.getElementById('clear-back').addEventListener('click',function(){const ctx = config.cavansDom.getContext("2d");ctx.globalCompositeOperation = "source-in";ctx.fillStyle = "rgba(0, 0, 0, 0.5)"; // 设置抠图的透明度ctx.fillRect(0, 0, canvas.width, canvas.height);})
}

效果对比
source-in
source-out效果

// 抠图
function clearColor(){document.getElementById('clear-back').addEventListener('click',function(){const ctx = config.cavansDom.getContext("2d");ctx.globalCompositeOperation = "source-out";ctx.fillStyle = "rgba(0, 0, 0, 0.5)"; // 设置抠图的透明度ctx.fillRect(0, 0, canvas.width, canvas.height);})
}

效果对比
source-out

💖cavans添加文字水印

要在JavaScript的canvas上添加文字水印,可以使用以下代码:

const canvas = document.getElementById("myCanvas");
const ctx = canvas.getContext("2d");
ctx.font = "30px Arial";
ctx.fillStyle = "rgba(0, 0, 0, 0.5)";
ctx.fillText("Watermark", 10, 50);

首先,通过getElementById函数获取到canvas元素,并通过getContext函数获取到2D绘图上下文对象ctx。

然后,设置字体样式和颜色,可以使用font属性和fillStyle属性,分别设置字体大小和颜色。

最后,使用fillText方法绘制文字水印,传入要显示的文字、x坐标和y坐标。
添加水印成功
watermask

💖inscode 完整代码块

⭐结束

本文分享到这结束,如有错误或者不足之处欢迎指出!
earth

👍 点赞,是我创作的动力!
⭐️ 收藏,是我努力的方向!
✏️ 评论,是我进步的财富!
💖 最后,感谢你的阅读!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

建设IAM/IDM统一身份管理,实现系统之间的单点登录(SSO)

企业实施身份管理的现状&#xff1a; 1.身份存储分散&#xff0c;不能统一供应诸多应用系统&#xff0c;企业用户信息常常存在于多个系统&#xff0c;如HR系统有一套用户信息&#xff0c;OA系统也有一套用户信息&#xff0c;身份存储不集中&#xff0c;不能统一地为诸多应用系…

AJAX概念和axios使用、URL、请求方法和数据提交、HTTP协议、接口、form-serialize插件

AJAX概念和axios使用 AJAX概念 AJAX就是使用XMLHttpRequest对象与服务器通信&#xff0c;它可以使用JSON、XML、HTML和text文本等格式发送和接收数据&#xff0c;AJAX最吸引人的就是它的异步特性&#xff0c;也就是说它可以在不重新刷新页面的情况下与服务器通信&#xff0c;…

Tomcat(二)

一、搭建个人博客 二、状态页 默认的管理页面被禁用&#xff0c;启用方法如下 修改conf/conf/tomcat-users.xml 2.1 开启状态页&#xff08;本地访问&#xff09; 2.2 开启允许远程登录状态页 2.3 host manager

【Spark编程基础】RDD 编程初级实践(附源代码)

目录 一、实验目的二、实验平台三、实验内容1.spark-shell 交互式编程2.编写独立应用程序实现数据去重3.编写独立应用程序实现求平均值问题 一、实验目的 1、熟悉 Spark 的 RDD 基本操作及键值对操作&#xff1b; 2、熟悉使用 RDD 编程解决实际具体问题的方法 二、实验平台 …

widget一些控件的使用

QRadioButton使用 先使用ui界面拖拽创建radio button #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);ui->male->setChecked(true);//选中按钮ui->o…

C语言字符串函数strstr、strtok和strerror

1.strstr函数 函数作用&#xff1a; 在字符串1中查找是否存在字符串2。 例子&#xff1a; "bbc"中找”bc“ 函数定义&#xff1a; const char * strstr ( const char * str1, const char * str2 ); str1字符串1的首字符的指针。str2字符串2的首字符的指针。const修…

2024/03/16----面试中遇到的一些面试题

1.请简单的说一下IOC&#xff0c;AOP 1.1 IOC 控制反转&#xff08;IOC&#xff09;是一种设计思想&#xff0c;就是将原本在程序中需要手动创建对象&#xff0c;现在交由Spring管理创建&#xff0c;从而降低代码之间的耦合度。 IoC 最常见以及最合理的实现方式叫做依赖注入…

ICANN备稿时debug遇到的问题

包问题 装包&#xff1a;先用fastai出现单击没有跳转的情况&#xff1a;安装pylance即可出现了用pip3 uninstall后pip3 list还有原来的numpy&#xff0c;然后用conda uninstall之后就行了。pip, pip3, conda这几个来回用。 精度问题 打印tensor数组自动保留后四位&#xff1a;…

threejs案例,与静态三角形网格的基本碰撞, 鼠标环顾四周并投球游戏

创建一个时钟对象: const clock new THREE.Clock();这行代码创建了一个新的THREE.Clock对象&#xff0c;它用于跟踪经过的时间。这在动画和物理模拟中很有用。 2. 创建场景: const scene new THREE.Scene();这行代码创建了一个新的3D场景。所有的物体&#xff08;如模型、灯…

git问题列表(一)(持续更新中~~~)

文章目录 问题1&#xff1a;如何在本地创建git仓库&#xff0c;并推送到远程仓库&#xff1f;问题2&#xff1a;如何创建本地分支&#xff0c;并基于其创建远程分支&#xff1f;问题3&#xff1a;报错“origin does not appear to be a git repository”是什么原因&#xff1f;…

如何在Ubuntu中查看编辑lvgl的demo和examples?

如何在Ubuntu中查看编辑lvgl的demo和examples&#xff1f; 如何在 Ubuntu系统中运行查看lvgl 1、拉取代码 在lvgl的github主页面有50多个仓库&#xff0c;找到lv_port_pc_eclipse这个仓库&#xff0c;点进去 拉取仓库代码和子仓库代码 仓库网址&#xff1a;https://github…

【php基础】输出、变量、

php基础补充 1. 输出2.和"的区别3.变量3.1变量的命名规则3.2 两个对象指向同一个值3.3 可变变量 4.变量的作用域5. 检测变量 1. 输出 echo: 输出 print: 输出&#xff0c;输出成功返回1 print_r(): 输出数组 var_dump(): 输出数据的详细信息&#xff0c;带有数据类型和数…

矩阵中移动的最大次数

文章目录 所属专栏:BFS算法 题目链接 思路如下&#xff1a; 1.首先我们需要从第一列开始遍历&#xff0c;寻找每一个都能够满足条件的位置&#xff0c;将它插入到数组里面 2.第一列遍历完了后我们先判断第一列的数是否都满足条件插入到数组里面&#xff0c;如果数组为空&#…

智障版本GPT3实现

背景,实现GPT3,采用python代码。调库hf及tf2.0+基础。 由于完全实现GPT模型及其预训练过程涉及大量的代码和计算资源,以下是一个基于TensorFlow 2.x的简化版GPT模型构建和调用的示例。请注意,这仅展示了模型的基本结构,实际运行需替换为真实数据集和预处理步骤,且无法直…

深入理解Transformer架构:从Seq2Seq到无监督预训练的演进

Transformer问答-2 根据我的了解&#xff0c;最开始Transformer的架构为encoderdecoder&#xff0c;是用于处理Seq2Seq任务的&#xff0c;后来GPT系列只采用decoder-only架构专注于next toke prediction任务&#xff0c;在我的认识当中&#xff0c;这两者都可以归为next toke …

基于粒子群算法的分布式电源配电网重构优化matlab仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 4.1基本PSO算法原理 4.2配电网重构的目标函数 5.完整工程文件 1.课题概述 基于粒子群算法的分布式电源配电网重构优化。通过Matlab仿真&#xff0c;对比优化前后 1.节点的电压值 2.线路的损耗,这里计…

18双体系Java学习之数组赋值和拷贝

数组赋值 数组拷贝 ★小贴士 Object src指定源数组&#xff0c; int srcPos指定复制开始的位置&#xff0c; Object dest指目标数组&#xff0c; int destPos指定复制的内容从哪个位置开始放置&#xff0c; int length 指复制的长度&#xff0c; 也就是说源数组中位置从 s…

ubuntu18.04安装ffmpeg

编译ffmpeg命令如下&#xff1a; 1.安装yasm wget http://www.tortall.net/projects/yasm/releases/yasm-1.3.0.tar.gz tar xvzf yasm-1.3.0.tar.gz cd yasm-1.3.0 ./configure make && make install2.安装nasm(2.13以上版本) wget https://www.nasm.us/pub/nasm/re…

如何解决Hexo个人博客上传GitHub后无法更新问题

HexoGitHub提供了一个轻量级、易于管理的平台&#xff0c;让大家可以轻松建立并维护自己的博客。然而&#xff0c;许多初次使用Hexo的朋友可能会遇到一个常见问题&#xff1a;在将博客上传到GitHub之后&#xff0c;对博客进行更新&#xff0c;但是网页上的内容却没有改变。本文…

linux环境下连接db2数据库的操作

linux环境下连接db2数据库的操作 1 查看db2连接相关信息2 建立连接3 取消连接4 测试连接 1 查看db2连接相关信息 su - db2inst1 ~]$ db2 list db directory ~]$ db2 list node directory ~]$ db2 list dcs directory2 建立连接 su - db2inst1 ~]$ db2 terminate ~]$ db2 cata…