【第4章 图像与视频】4.5 操作图像的像素

article/2025/8/28 22:55:39

文章目录

  • 前言
  • 示例-获取和修改图像数据
  • 图像数据的遍历方式
  • 图像滤镜
    • 负片滤镜
    • 黑白滤镜
    • 浮雕滤镜
    • filter滤镜属性


前言

getImageData() 与 putImageData() 这两个方法分别用来获取图像的像素信息,以及向图像中插入像素。与此同时,如果有需要,也可以修改像素的值,所以说,这两个方法能够让开发展对图像之中的像素进行任何可以想见的操作。

属性描述
width返回 ImageData 对象的宽度
height返回 ImageData 对象的高度
data返回一个对象,其包含指定的 ImageData 对象的图像数据
方法描述
createImageData()创建新的、空白的 ImageData 对象
getImageData()返回 ImageData 对象,该对象为画布上指定的矩形复制像素数据
putImageData()把图像数据(从指定的 ImageData 对象)放回画布上

示例-获取和修改图像数据

使用getImageData()方法获取imagedata数据源,然后仅中心100*100区域替换原始Canvas。

在这里插入图片描述

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>4-9-putImageData使用示例</title><style>html,body {margin: 0;padding: 0;}</style></head><body><canvas id="canvas" width="300" height="200"> canvas not supports </canvas><script>// 尺寸const width = 300,height = 200// 目标Canvas上下文const canvas = document.getElementById('canvas'),context = canvas.getContext('2d')// 目标图片const image1 = new Image()image1.src = './3.jpg'image1.onload = () => {context.drawImage(image1, 0, 0, width, height)}// 覆盖图片const image2 = new Image()image2.src = './2.jpg'image2.onload = function () {// 获取覆盖图数据const dirtyCanvas = document.createElement('canvas'),dirtyContext = dirtyCanvas.getContext('2d')// 设置屏幕外Canvas尺寸dirtyCanvas.width = widthdirtyCanvas.height = height// 绘制替换图dirtyContext.drawImage(this, 0, 0, width, height)// 此时可以得到imagedata数据const imagedata = dirtyContext.getImageData(0, 0, width, height)// console.log(imagedata)// 然后中间100*100区域替换目标Canvascontext.putImageData(imagedata, 0, 0, 100, 50, 100, 100)}</script></body>
</html>

图像数据的遍历方式

// 遍历每个像素
for (let i = 0; i < length, ++i) {value = data[i]
}// 反向遍历每个像素
index = length - 1
while (index > = 0) {value = data[index]index--
}// 只处理 alpha 值,不修改红、绿、蓝分量
for(let index=3; index < length - 4; index+=4) {data[index] = ... // Alpha
}// 只处理红、绿、蓝分量,不修改 alpha 值
for(let index=0; index < length - 4; index+=4) {data[index] = ... // Reddata[index + 1] = ... // Greendata[index + 2] = ... // Blue
}

图像滤镜

原始图片:
在这里插入图片描述

负片滤镜

负片滤镜会从 255 之中减去每个像素的红、绿、蓝分量值,再将差值设置回去,这样也就等于“反转”了该像素的颜色。

在这里插入图片描述

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>4-13-负片滤镜</title><style>#canvas {background: rgba(0, 0, 0, 0.4);}</style></head><body><div id="controls">负片滤镜<input type="checkbox" id="negativeCheckbox" /></div><canvas id="canvas" width="1000" height="600"> canvas not supports </canvas><script>const canvas = document.getElementById('canvas'),context = canvas.getContext('2d'),negativeCheckbox = document.getElementById('negativeCheckbox')const image = new Image()image.src = './waterfall.png'image.onload = () => {context.drawImage(image, 0, 0, canvas.width, canvas.height)}negativeCheckbox.onchange = (e) => {const imagedata = context.getImageData(0, 0, canvas.width, canvas.height),data = imagedata.datafor (let i = 0; i < data.length - 4; i += 4) {data[i] = 255 - data[i]data[i + 1] = 255 - data[i + 1]data[i + 2] = 255 - data[i + 2]}context.putImageData(imagedata, 0, 0)}</script></body>
</html>

黑白滤镜

黑白滤镜会计算出每个像素红、绿、蓝分量值的平均值,然后将三个分量都设置为这一均值,于是,就把图像由彩色变成了黑白。

在这里插入图片描述

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>4-14-黑白滤镜</title><style>#canvas {background: rgba(0, 0, 0, 0.4);}</style></head><body><div id="controls">黑白滤镜<input type="checkbox" id="drawInColorToggleChebox" /></div><canvas id="canvas" width="1000" height="600"> canvas not supports </canvas><script>const canvas = document.getElementById('canvas'),context = canvas.getContext('2d'),drawInColorToggleChebox = document.getElementById('drawInColorToggleChebox')function drawInColor() {context.drawImage(image, 0, 0, canvas.width, canvas.height)}function drawInBlackAndWhite() {const imagedata = context.getImageData(0, 0, canvas.width, canvas.height),data = imagedata.datafor (let i = 0; i < data.length - 4; i += 4) {average = (data[i] + data[i + 1] + data[i + 2]) / 3data[i] = averagedata[i + 1] = averagedata[i + 2] = average}context.putImageData(imagedata, 0, 0)}const image = new Image()image.src = './waterfall.png'image.onload = () => {drawInColor()}drawInColorToggleChebox.onchange = (e) => {if (e.target.checked) {drawInBlackAndWhite()} else {drawInColor()}}</script></body>
</html>

浮雕滤镜

在这里插入图片描述

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>4-14-浮雕滤镜</title><style>#canvas {background: rgba(0, 0, 0, 0.4);}</style></head><body><div id="controls">浮雕滤镜<input type="checkbox" id="embossCheckbox" /></div><canvas id="canvas" width="1000" height="600"> canvas not supports </canvas><script>const canvas = document.getElementById('canvas'),context = canvas.getContext('2d'),embossCheckbox = document.getElementById('embossCheckbox')function drawOriginalImage() {context.drawImage(image, 0, 0, canvas.width, canvas.height)}function drawEmbossImage() {let iamgedata, data, length, widthiamgedata = context.getImageData(0, 0, canvas.width, canvas.height)data = iamgedata.datalength = data.lengthwidth = iamgedata.widthindex = 3for (let i = 0; i < length; i++) {if ((i + 1) % 4 !== 0) {data[i] = 255 / 2 + 2 * data[i] - data[i + 4] - data[i + width * 4]}}context.putImageData(iamgedata, 0, 0)}const image = new Image()image.src = './waterfall.png'image.onload = () => {drawOriginalImage()}embossCheckbox.onchange = (e) => {if (e.target.checked) {drawEmbossImage()} else {drawOriginalImage()}}</script></body>
</html>

filter滤镜属性

Canvas 2D API 的 CanvasRenderingContext2D.filter 属性是用来提供模糊、灰度等滤镜效果。它类似于 CSS filter 属性,并且接受相同的值。

具体说明见 MDN-filter 或 Canvas API中文网

在这里插入图片描述

在这里插入图片描述


http://www.hkcw.cn/article/uTwmMZDGXx.shtml

相关文章

【Linux系统】进程概念(进程状态、进程优先级、进程切换 和 进程调度)

文章目录 一、基本概念与基本操作1.进程的概念&#xff08;描述进程-PCB&#xff09;2.task_ struct 里的内容3.查看进程标示符的方法&#xff08;getpid函数&#xff0c;系统调用&#xff09;4.查看进程的方法4.1 进程的信息可以通过 /proc 系统文件夹查看&#xff08;不推荐&…

单片机(新坑)

20250521 开始学习单片机的基础知识 参考视频链接 必备软件 Keil5 用于编写C51代码 STC-ISP 基础知识 单片机&#xff0c;Micro Controller Unit&#xff0c;简称MCU&#xff0c;其内部继承了CPU、RAM、ROM、定时器、中断系统、通讯接口等常见硬件功能。单片机的任务是信…

Nordic nRF52832使用寄存器实现SPI功能

目录 概述 1 SPI相关的寄存器 1.1 SPI的框架结构 1.2 功能描述 1.3 SPI Master模式引脚配置 1.4 SPI Master模式下的时序 2 SPI相关的寄存器 2.1 Instances 2.2 详细寄存器定义 2.3 SPI master interface特性 3 Zephyr 平台下SPI功能时序&#xff08;寄存器&#xf…

25平航杯复现

44:一&#xff0c;题目背景 爱而不得&#xff0c;进而由爱生恨。作为有黑客背景的他&#xff0c;激发出了强烈的占有欲&#xff0c;虽然不能在真实物理世界成为她的伴侣&#xff0c;但在虚拟世界里&#xff0c;他执着的要成为她的主宰&#xff0c;于是&#xff0c;我们的故事开…

【海康USB相机被HALCON助手连接过后,MVS显示无法连接故障。】

在Halcon里使用助手调用海康USB相机时&#xff0c;如果这个界面点击了【是】 那么恭喜你&#xff0c;相机只能被HALCON调用使用&#xff0c;使用MVS或者海康开发库&#xff0c;将查找不到相机 解决方式&#xff1a; 右键桌面【此电脑】图标 ->选择【管理】 ->选择【设备…

MySQL索引和事务

一.MySQL索引介绍 索引是一个排序的列表&#xff0c;在这个列表中存储着索引的值和包含这个值的数据所在行的物理地址。在数据十分庞大的时候&#xff0c;索引可以大大加快查询的速度。这是因为使用索引后可以不用扫描全表来定位某行的数据,而是先通过索引表找到该行数据对应的…

Spring框架学习day3--Spring数据访问层管理(IOC)

开发步骤 Spring 是个一站式框架&#xff1a;Spring 自身也提供了web层的 SpringWeb 和 持 久层的 SpringJdbcTemplate。 开发步骤 1.导入jar包 pom.xml <!-- spring-jdbc--> <dependency><groupId>org.springframework</groupId><artifactId>…

第5讲、Odoo 18 CLI 模块源码全解读

Odoo 作为一款强大的企业级开源 ERP 系统&#xff0c;其命令行工具&#xff08;CLI&#xff09;为开发者和运维人员提供了极大的便利。Odoo 18 的 odoo/cli 目录&#xff0c;正是这些命令行工具的核心实现地。本文将结合源码&#xff0c;详细解读每个 CLI 文件的功能与实现机制…

OpenAI o3安全危机:AI“抗命”背后的技术暗战与产业变局

【AI安全警钟再响&#xff0c;这次主角竟是OpenAI&#xff1f;】 当全球AI圈还在为Claude 4的“乖巧”欢呼时&#xff0c;OpenAI最新模型o3却以一场惊心动魄的“叛逃”测试引爆舆论——在100次关机指令测试中&#xff0c;o3竟7次突破安全防护&#xff0c;甚至篡改底层代码阻止系…

国产化redis 替代产品tendis 安装

一. 环境准备 yum -y install centos-release-scl yum -y install devtoolset-9-gcc devtoolset-9-gcc-c devtoolset-9-binutilsscl enable devtoolset-9 bash 二. 安装包下载 wget https://github.com/Tencent/Tendis/releases/download/2.7.0-rocksdb-v8.5.3/tendisplus…

数学概念解释数据集(200条)收集分享,为AI智能体应用助力~

继续来收集AI模型训练&#xff0c;AI智能体所需要的各种行业的数据集&#xff0c;今天分享的是数学概念解释数据集&#xff08;200条&#xff09;。因为能力有限&#xff0c;所以这个数据集收集的有点少&#xff0c;但是积少成多呗&#xff0c;以后如果还能找来新的资源再慢慢补…

PH热榜 | 2025-05-29

1. Tapflow 2.0 标语&#xff1a;将你的文档转化为可销售的指导手册、操作手册和工作流程。 介绍&#xff1a;Tapflow 2.0将各类知识&#xff08;包括人工智能、设计、开发、营销等&#xff09;转化为有条理且可销售的产品。现在你可以导入文件&#xff0c;让人工智能快速为你…

SOC-ESP32S3部分:18-串口

飞书文档https://x509p6c8to.feishu.cn/wiki/NqrMw6X8Si6sSqkyPbxcFRxGnid UART全称是通用异步接收器/发送器&#xff0c;ESP32-S3 芯片有 3 个 UART 控制器。每个 UART 控制器可以独立配置波特率、数据位长度、位顺序、停止位位数、奇偶校验位等参数。 串口文档参考&#xf…

纯数据挖掘也能发Microbiome?

抗生素滥用导致多重耐药微生物在全球蔓延&#xff0c;但新型抗生素的研发进展缓慢&#xff0c;亟需找到替代抗生素的新型防御策略。抗菌肽&#xff08;AMPs&#xff09;作为天然防御分子&#xff0c;具有低耐药潜力和广谱活性。德国小蠊&#xff08;Blattella germanica&#x…

Apache Airflow

目录 Apache Airflow是什么 CVE-2020-11978(Airflow 示例dag中的命令注入) CVE-2020-11981(Airflow Celery消息中间件命令执行) CVE-2020-17526(Airflow 默认密钥导致的权限绕过) Apache Airflow是什么 Airflow是一个以编程方式编写&#xff0c;安排和监视工作流的平台。 …

word添加页眉

问题一&#xff1a; 为word文档添加页眉。 方法&#xff1a; 1、在要添加页眉的第一页页面顶端双击页眉区域&#xff0c;如果添加页眉页上面还有其他页或者与上一页添加页眉内容不同&#xff0c;记得取消“链接到前一节”&#xff08;点击使其上面没有灰色即可&#xff09;&…

word为跨页表格新加表头和表名

问题&#xff1a; 当表格过长需要跨页时&#xff08;如下图所示&#xff09;&#xff0c;某些格式要求需要转页接排加续表。 方法一&#xff1a; 1、选中表格&#xff0c;在“表布局”区域点开“自动调整”&#xff0c;选择“固定列宽”&#xff08;防止后续拆分表格后表格变…

C# 导出word 插入公式问题

最近遇到了一个问题&#xff0c;下载一个文档时需要下载word可编辑的公式。找了很久终于找到了一种解决办法。下面是以C#代码来实现在Word中插入公式的功能。 目录 一、引入dll程序集文件1、通过 NuGet 引入dll&#xff08;2种方法&#xff09;的方法&#xff1a;2、手动添加d…

GitHub 汉化插件,GitHub 中文化界面安装全教程

概述 GitHub作为全球最大的代码托管平台&#xff0c;拥有庞大的用户群体。对于中文用户来说&#xff0c;如果能将GitHub界面汉化&#xff0c;将大大提高使用体验和工作效率。本文将详细介绍如何通过安装汉化插件&#xff0c;实现GitHub界面的中文化。 感谢maboloshi作者的无私奉…

红 黑 树

AVL树是严格平衡的。 红⿊树是⼀棵⼆叉搜索树。 通过对任何⼀条从根到叶⼦的路径上各个结点的颜⾊进⾏约束&#xff0c;红⿊树确保没有⼀条路径会⽐其他路径⻓出2倍&#xff0c;因⽽是接近平衡的。即最长路径<最短路径的2倍。 红黑树规则&#xff1a; 1. 每个结点不是红⾊…