【canvas】canvas基础使用(七):绘制图像

简言

学习canvas如何绘制图片或视频。

绘制图像

给定一个图像,一般使用drawImage()方法绘制。

drawImage 绘制图像

Canvas 2D API 中的 CanvasRenderingContext2D.drawImage() 方法提供了多种在画布(Canvas)上绘制图像的方式。
语法:
指定绘制位置快速绘制:
drawImage(image, dx, dy);
指定绘制位置宽高快速绘制:
drawImage(image, dx, dy, dWidth, dHeight);
指定图像被绘制区域和绘制区域绘制:
drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
在这里插入图片描述

使用方法有三种

参数:

  • image
    绘制到上下文的元素。允许任何的画布图像源,例如:HTMLImageElement、SVGImageElement (en-US)、HTMLVideoElement、HTMLCanvasElement、ImageBitmap、OffscreenCanvas 或 VideoFrame (en-US)。

  • sx 可选
    需要绘制到目标上下文中的,image 的矩形(裁剪)选择框的左上角 X 轴坐标。可以使用 3 参数或 5 参数语法来省略这个参数。

  • sy 可选
    需要绘制到目标上下文中的,image 的矩形(裁剪)选择框的左上角 Y 轴坐标。可以使用 3 参数或 5 参数语法来省略这个参数。

  • sWidth 可选
    需要绘制到目标上下文中的,image 的矩形(裁剪)选择框的宽度。如果不说明,整个矩形(裁剪)从坐标的 sx 和 sy 开始,到 image 的右下角结束。可以使用 3 参数或 5 参数语法来省略这个参数。使用负值将翻转这个图像。

  • sHeight 可选
    需要绘制到目标上下文中的,image的矩形(裁剪)选择框的高度。使用负值将翻转这个图像。

  • dx
    image 的左上角在目标画布上 X 轴坐标。

  • dy
    image 的左上角在目标画布上 Y 轴坐标。

  • dWidth
    image 在目标画布上绘制的宽度。允许对绘制的 image 进行缩放。如果不说明,在绘制时 image 宽度不会缩放。注意,这个参数不包含在 3 参数语法中。

  • dHeight
    image 在目标画布上绘制的高度。允许对绘制的 image 进行缩放。如果不说明,在绘制时 image 高度不会缩放。注意,这个参数不包含在 3 参数语法中。

注意

  • 当 drawImage() 需要在 HTMLVideoElement 工作时,仅当 HTMLMediaElement.readyState 大于 1 时 drawImage() 才能正常工作。
  • 在绘制,裁剪和/或缩放时,drawImage() 将始终使用源元素的固有尺寸(以 CSS 像素为单位)。
  • 在某些旧版本浏览器中,drawImage() 将忽略图像中的所有 EXIF 元数据,包括方向。此行为在 iOS 设备上尤其麻烦。你应该自己检测方向并使用 rotate() 使其正确。

示例

const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
const image = document.getElementById("source");image.addEventListener("load", (e) => {ctx.drawImage(image, 33, 71, 104, 124, 21, 20, 87, 104);
});

ImageData 绘制图像

获得一个ImageData 对象后,使用putImageData()方法绘制。

可以通过CanvasRenderingContext2D.getImageData()获得一个ImageData 对象,用来描述 canvas 区域隐含的像素数据。

语法:
ImageData ctx.getImageData(sx, sy, sw, sh);
参数:

  • sx
    将要被提取的图像数据矩形区域的左上角 x 坐标。

  • sy
    将要被提取的图像数据矩形区域的左上角 y 坐标。

  • sw
    将要被提取的图像数据矩形区域的宽度。

  • sh
    将要被提取的图像数据矩形区域的高度。

getImageData()

CanvasRenderingContext2D.getImageData() 返回一个ImageData对象,用来描述 canvas 区域隐含的像素数据,这个区域通过矩形表示,起始点为*(sx, sy)、宽为sw、高为sh。*

putImageData()

CanvasRenderingContext2D.putImageData() 是 Canvas 2D API 将数据从已有的 ImageData 对象绘制到位图的方法。如果提供了一个绘制过的矩形,则只绘制该矩形的像素。此方法不受画布转换矩阵的影响。
语法:
void ctx.putImageData(imagedata, dx, dy);
void ctx.putImageData(imagedata, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight);
参数:

  • imageData
    ImageData,包含像素值的数组对象。

  • dx
    源图像数据在目标画布中的位置偏移量(x 轴方向的偏移量)。

  • dy
    源图像数据在目标画布中的位置偏移量(y 轴方向的偏移量)。

  • dirtyX 可选
    在源图像数据中,矩形区域左上角的位置。默认是整个图像数据的左上角(x 坐标)。

  • dirtyY 可选
    在源图像数据中,矩形区域左上角的位置。默认是整个图像数据的左上角(y 坐标)。

  • dirtyWidth 可选
    在源图像数据中,矩形区域的宽度。默认是图像数据的宽度。

  • dirtyHeight 可选
    在源图像数据中,矩形区域的高度。默认是图像数据的高度。

示例

<!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"><title>图像剪辑</title><style>html,body {width: 100vw;height: 100%;margin: 0;padding: 0;}.box {box-sizing: border-box;width: 100%;height: 100%;padding: 24px;}.box-content {margin-top: 16px;box-sizing: border-box;width: 100%;/* height: 500px; *//* display: flex; */align-items: center;text-align: center;border: 1px solid #000;}#origin {width: 500px;height: 500px;border: 1px solid #000;}</style>
</head><body><div class="box"><div><h1>图像查看</h1><input type="file" name="file" id="file"></div><div class="box-content"><canvas id="origin" width="500" height="500"></canvas></div><div></div></div><script>const file = document.getElementById('file');const origin = document.getElementById('origin');const ctx = origin.getContext('2d');const img = document.createElement('img');//  辅助线let fx = 0let fy = 0let showf = false//  图片缩放let scale = 1 //  图片缩放比例let dx = 0 //  图片偏移 xlet dy = 0//  图片偏移 ylet dw = origin.widthlet dh = origin.heightlet modify = falseorigin.addEventListener("mousedown", (e) => {modify = trueshowf = truelastX = e.offsetXlastY = e.offsetY});origin.addEventListener("mousemove", (e) => {if (!ctx) returnlet x = e.offsetXlet y = e.offsetYif (modify) {fx = xfy = ydx += (x - lastX)dy += (y - lastY)lastX = xlastY = ydrawOperatingLine()}})origin.addEventListener('mouseup', (e) => {if (modify) {modify = falseshowf = falsedrawOperatingLine()}})origin.addEventListener("contextmenu", (e) => {e.preventDefault()if (img.width > img.height) {scale = origin.width / img.width} else {scale = origin.height / img.height}dx = (origin.width - scale * img.width) / (origin.width / e.offsetX)dy = (origin.height - scale * img.height) / (origin.height / e.offsetY)drawOperatingLine()})origin.addEventListener('wheel', (e) => {const { deltaY } = eif (deltaY > 0) { // 下滑放大scale += 0.1} else if (scale > 0.1) { // 上滑缩小scale -= 0.1}dx = (origin.width - scale * img.width) / (origin.width / e.offsetX)dy = (origin.height - scale * img.height) / (origin.height / e.offsetY)drawOperatingLine()})file.addEventListener('change', (e) => {const file = e.target.files[0];const reader = new FileReader();reader.readAsDataURL(file);reader.onload = (e) => {img.src = e.target.result;img.onload = () => {//  更新图片缩放比例if (img.width > img.height) {scale = origin.width / img.width} else {scale = origin.height / img.height}drawOperatingLine(true)}}})//  绘制裁剪控制图像function drawOperatingLine(init = false) {ctx.clearRect(0, 0, origin.width, origin.height)//  绘制图像dx = init ? (origin.width - scale * img.width) / 2 : dx  //  图片偏移 xdy = init ? (origin.height - scale * img.height) / 2 : dy //  图片偏移 ydw = scale * img.widthdh = scale * img.heightctx.drawImage(img, 0, 0, img.width, img.height, dx, dy, dw, dh);//  辅助线if (showf) {ctx.save()ctx.beginPath();ctx.strokeStyle = 'red'ctx.setLineDash([3, 3])ctx.moveTo(0, fy);ctx.lineTo(origin.width, fy);ctx.moveTo(fx, 0);ctx.lineTo(fx, origin.height);ctx.stroke();ctx.restore()}}</script>
</body></html>

在这里插入图片描述

结语

结束了。

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

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

相关文章

python连接mysql步骤

要在 Python 中连接 MySQL 数据库&#xff0c;你需要遵循以下步骤&#xff1a; 步骤 1: 安装 MySQL Connector/Python 首先&#xff0c;确保你的系统中已安装了 MySQL Connector/Python&#xff0c;这是 MySQL 官方提供的用于在 Python 中连接 MySQL 的驱动程序。你可以通过 …

为什么内存要对齐

1.硬件要求&#xff1a; 许多处理器和硬件架构对于特定数据类型的访问要求内存地址是对齐的。例如&#xff0c;某些处理器可能要求访问4字节整数的地址必须是4的倍数&#xff0c;否则可能会导致性能下降甚至错误。因为可能会导致额外的处理器周期用于处理未对齐的访问&#xff…

Swift中的类

在Swift中&#xff0c;类是一种复合类型&#xff0c;用于创建具有属性和方法的对象。它是面向对象编程的基本构建块之一。 以下是一个简单的类的示例&#xff1a; class Person {var name: Stringvar age: Intinit(name: String, age: Int) {self.name nameself.age age}fu…

四川易点慧电子商务抖音小店安全:护航您的在线交易之旅

在数字化浪潮席卷全球的今天&#xff0c;电子商务已经成为人们日常生活的重要组成部分。四川易点慧电子商务抖音小店作为新兴的电商平台&#xff0c;以其便捷、高效的特点吸引了众多消费者的目光。然而&#xff0c;随着网络交易的日益频繁&#xff0c;安全问题也日益凸显。本文…

揭秘!这些部门对六西格玛技术情有独钟

当下&#xff0c;企业为了提升产品质量、降低成本、提高效率&#xff0c;纷纷寻求先进的管理方法和技术手段。其中&#xff0c;六西格玛技术因其卓越的绩效改善能力&#xff0c;受到了众多企业的青睐。那么&#xff0c;哪些部门对六西格玛技术情有独钟呢&#xff1f;天行健六西…

如何使用Docker部署WPS Office服务并实现无公网IP远程处理文档表格

文章目录 1. 拉取WPS Office镜像2. 运行WPS Office镜像容器3. 本地访问WPS Office4. 群晖安装Cpolar5. 配置WPS Office远程地址6. 远程访问WPS Office小结 7. 固定公网地址 wps-office是一个在Linux服务器上部署WPS Office的镜像。它基于WPS Office的Linux版本&#xff0c;通过…

每日一题(leetcode765):情侣牵手--并查集和哈希表

代码技巧&#xff0c;在读取列表时都除2&#xff0c;符合情理并且节省了空间。 class Solution { private:int get(vector<int>& f,int x){if(f[x]x){return x;}int newxget(f,f[x]);return newx;}void add(vector<int>& f,int a,int b){int zuaget(f,a);…

EPSON的RX8900CE适合用于安防摄像头产品

安防摄像头产品可以实现视频监控&#xff0c;运动检测&#xff0c;人脸识别等功能&#xff0c;并且可以支持远程访问&#xff0c;成了用户的“千里眼”。之前安防摄像头的价格比较高&#xff0c;一般比较重要的场合才会使用&#xff0c;目前随着安防摄像头价格逐渐降低&#xf…

MASA Framework系列-在电商领域的应用(7)

MASA Framework在电商领域的应用实例可以体现其强大的微服务架构和丰富的功能组件。以下是一个基于MASA Framework构建的电商实例的概述&#xff1a; 一、系统架构 该电商系统采用了MASA Framework的微服务架构&#xff0c;将各个功能模块拆分为独立的服务&#xff0c;如用户…

一进四出学生宿舍智能电表

一进四出学生宿舍电表功能特点** 一、多路电能计量** 该电表采用先进的电路设计&#xff0c;能够同时实现四路电能的独立计量。每路输出都可以单独控制和管理&#xff0c;方便对学生宿舍中各个用电设备的电能消耗进行精确统计。 二、实时电量显示** 电表配备有高清LED显示屏…

用四种方法实现轮播图

1、css3动画实现的轮播图 实现原理如下&#xff1a; 1、设置大的div a)设置绝对定位&#xff0c;定位位置&#xff1b; b)设置图片展示出来的高度和宽度&#xff08;height和width&#xff09;&#xff1b; c)设置overflow:hidden;设置超出部分隐藏&#xff1b;使得图片只能在…

[学习笔记] 网络安全 bp爆破

我们用的靶场是用的一个皮卡丘的漏洞练习平台的一个靶场首先要开启浏览器代理&#xff0c;然后开启在bp上开启就是拦截代理模块里面的拦截它有4个攻击模式&#xff0c;分别是&#xff1a; Sniper&#xff08;狙击手&#xff09;&#xff1a;这种攻击方式主要是将包内各个用$$符…

NL2SQL进阶系列(5):论文解读业界前沿方案(DIN-SQL、C3-SQL、DAIL-SQL)、新一代数据集BIRD-SQL解读

NL2SQL进阶系列(5):论文解读业界前沿方案(DIN-SQL、C3-SQL、DAIL-SQL)、新一代数据集BIRD-SQL解读 NL2SQL基础系列(1):业界顶尖排行榜、权威测评数据集及LLM大模型(Spider vs BIRD)全面对比优劣分析[Text2SQL、Text2DSL] NL2SQL基础系列(2):主流大模型与微调方法精选集…

代码对比同步辅助工具,提高开发效率

一开始只是开发抖音的程序&#xff0c;后面复制代码去改成快手、小红书、拼多多等平台的程序。 然后一有些修改调整&#xff0c;可能需要同步到其他平台的代码中&#xff1b; 每次需要打开一个或者多个开发工具IDE&#xff0c;每个IDE打开一个项目&#xff0c;再去对照路径翻…

淘宝天猫商品详情API接口(商品详情页面数据接口,商品销量接口)

淘宝天猫商品详情API接口主要包括商品详情页面数据接口和商品销量接口。这些接口为商家和开发者提供了获取淘宝天猫平台上商品详细信息和销量数据的途径。 商品详情页面数据接口&#xff1a; 通过商品详情页面数据接口&#xff0c;商家和开发者可以获取到商品的详细信息&…

【Java探索之旅】数组概念与初始化指南:动静结合

&#x1f3a5; 屿小夏 &#xff1a; 个人主页 &#x1f525;个人专栏 &#xff1a; Java编程秘籍 &#x1f304; 莫道桑榆晚&#xff0c;为霞尚满天&#xff01; 文章目录 &#x1f4d1;前言一、初识数组1.1 为什么要有数组&#xff1f;1.2 数组的的概念 二、数组的创建及初始化…

python学习之:数据类型

大纲&#xff1a; 一、列表list的定义语法 1、 """" 演示数据类型&#xff1a;list列表 语法&#xff1a;变量 [元素1&#xff0c;元素2&#xff0c;元素3&#xff0c;......] """ # 定义一个列表list name_list [itheima, itcast, pyt…

8款AI绘画工具推荐,让你绘画更加生动有趣

大家好&#xff0c;我是你们的AI绘画导购员小助手&#xff01;今天我给大家带来了8款超级厉害的AI绘画工具推荐&#xff0c;它们不仅能让你的绘画更加生动有趣&#xff0c;还能让你的创作达到一个新的高度&#xff01; "爱制作AI"---这是一款非常好用的 AI 写作工具&…

TypeScript-官方基础模板创建的小程序,如何创建js文件

如何创建JS文件&#xff0c;不需要寻找“js”文件类型&#xff0c;只需要创建一个新的“文件”即可。 第一步:先删除 ts文件;如 index.ts 第二步:右键点击项目&#xff0c;选择“新建”&#xff0c;然后选择“文件”。 第三步:在弹出的界面中&#xff0c;在“文件名”中输入“…

ssm051网上医院预约挂号系统+jsp

网上医院预约挂号系统设计与实现 摘 要 如今的信息时代&#xff0c;对信息的共享性&#xff0c;信息的流通性有着较高要求&#xff0c;因此传统管理方式就不适合。为了让医院预约挂号信息的管理模式进行升级&#xff0c;也为了更好的维护医院预约挂号信息&#xff0c;网上医院…