【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,一经查实,立即删除!

相关文章

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

在数字化浪潮席卷全球的今天&#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…

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

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

用四种方法实现轮播图

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

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

一开始只是开发抖音的程序&#xff0c;后面复制代码去改成快手、小红书、拼多多等平台的程序。 然后一有些修改调整&#xff0c;可能需要同步到其他平台的代码中&#xff1b; 每次需要打开一个或者多个开发工具IDE&#xff0c;每个IDE打开一个项目&#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;网上医院…

pycharm配置anaconda环境时找不到python.exe解决办法

在一台新电脑上配置anaconda环境时&#xff0c;发现pycharm在设置解释器时&#xff0c;在conda环境中找不到anaconda已经创建好的python解释器可执行文件python.exe&#xff0c;其显示如下&#xff1a; 上图只显示创建的虚拟环境中的那些文件夹&#xff0c;但是没有显示这个虚拟…

【Java】SpringBoot快速整合mongoDB

目录 1.什么是mongoDB&#xff1f; 2.Docker安装mongoDB 3.SpringBoot整合mongoDB步骤 4.验证 1.什么是mongoDB&#xff1f; MongoDB是一种非关系型数据库&#xff0c;被广泛用于大型数据存储和分布式系统的构建。MongoDB支持的数据模型比传统的关系型数据库更加灵活&#x…

【Node.js】Express学习笔记(黑马)

目录 初识 ExpressExpress 简介Express 的基本使用托管静态资源nodemon Express 路由路由的概念路由的使用 Express 中间件中间件的概念Express 中间件的初体验中间件的分类 初识 Express Express 简介 什么是 Express&#xff1f; 官方给出的概念&#xff1a;Express 是基于…

这个Python神器,能让你摸半天鱼!

今天给大家分享一个炒鸡炒鸡简单又好用的神器——pampy。 我敢以我的荣誉保证&#xff0c;用了它之后&#xff0c;你写代码的效率可以蹭蹭蹭地提升&#xff01; Pampy 是哪路神仙 首先普及一下模式匹配。 模式匹配即给定某种模式&#xff0c;用这种模式去检查序列或字符串是…

前端页面显示时间与数据库时间差8小时

环境 jdk11mysql 8.0docker部署的 问题 突然发现页面上的数据比数据库的时间差了八个小时&#xff0c;然后我就开始排查问题。 首先看数据库的信息&#xff0c;发现时间都是没错的。 然后看一下ymal文件&#xff0c;是否是数据源链接写的有问题。 spring:datasource:url:…

NzN的数据结构--外排序

接上文&#xff0c;本篇向大家简单展示一下外排序的实现。先三连后看才是好习惯&#xff01;&#xff01;&#xff01; 在我们刚接触数据结构的时间里&#xff0c;我们只需要对外排序简单了解一下即可&#xff0c;重点要掌握的还是前面我们介绍的比较排序和非比较排序里的计数排…

蓝色系UX/UI设计求职面试作品集模版figmasketchPPT可编辑源文件

页面数量: 20P 页面尺寸:1920*1080PX 交付格式&#xff1a;figma、sketch、PPT 赠送文件&#xff1a;24款高质量样机&#xff08;PSD格式&#xff09; 该作品集虽然只有20页&#xff0c;但可根据需求复制作品集里已有的页面作为模版来扩展您的设计项目 该作品集模版可编辑可修…