接着上文[js高手之路] html5 canvas系列教程 - 状态详解(save与restore),相信大家都应该玩过美颜功能,而我们今天要讲的就是canvas强大的像素处理能力,通过像素处理,实现反色,黑白,亮度,复古,蒙版,透明等美颜效果.

getImageData:获取一张图片的像素数据

cxt.getImageData( x, y, width, height )

x:图片所在的x坐标

y: 图片所在的y坐标

width,height 要获取的像素区域

返回值是一个对象,对象包括一个data属性, 宽度,高度. data属性是一个巨大的数组,数组中存储的是这张图片的所有像素信息,每四个一组组成一个像素点的信息,如:

[r1,g1,b1,a1, r2,g2,b2,a2...], r( 红色) g( 绿色) b( 蓝色 ) a( 透明度 )

putImageData:输出像素图片

putImageData( 像素对象, x, y )

注意:getImageData会产生跨域问题,所以你的程序要放在web服务器下,我这里是放在phpstudy下面.

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset='utf-8' />
<style>
#canvas {
border: 1px dashed #aaa;
}
</style>
<script>
window.onload = function () {
var oCanvas = document.querySelector("#canvas"),
oGc = oCanvas.getContext('2d'); var oImg = new Image();
oImg.src = './img/mv.jpg';
oImg.onload = function () {
oGc.drawImage(oImg, 10, 10);
var imgData = oGc.getImageData(10, 10, 200, 200);
console.log( imgData );
}
}
</script>
</head>
<body>
<canvas id="canvas" width="500" height="400"></canvas>
</body>
</html>

我这张图片的尺寸是200 x 200.

一:反色效果

算法:把每一个像素的r, g, b颜色取反就行,也就是( 255 - 原来的值 )

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset='utf-8' />
<style>
#canvas {
border: 1px dashed #aaa;
}
</style>
<script>
window.onload = function () {
var oCanvas = document.querySelector("#canvas"),
oGc = oCanvas.getContext('2d'); var oImg = new Image();
oImg.src = './img/mv.jpg';
oImg.onload = function () {
oGc.drawImage(oImg, 10, 10);
var imgData = oGc.getImageData(10, 10, 200, 200),
data = imgData.data;
for( var i = 0; i < data.length; i += 4 ) {
data[i] = 255 - data[i];
data[i+1] = 255 - data[i+1];
data[i+2] = 255 - data[i+2];
}
//处理完之后,再次输出
oGc.putImageData( imgData, 220, 10 );
}
}
</script>
</head>
<body>
<canvas id="canvas" width="500" height="400"></canvas>
</body>
</html>

二、黑白效果(灰度图)

将彩色图片转换成黑白图片,原理:求r(data[i]), g(data[i+1]), b(data[i+2])三个通道的平均值,然后把这个平均值赋值给r, g, b

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset='utf-8' />
<style>
#canvas {
border: 1px dashed #aaa;
}
</style>
<script>
window.onload = function () {
var oCanvas = document.querySelector("#canvas"),
oGc = oCanvas.getContext('2d'); var oImg = new Image();
oImg.src = './img/mv.jpg';
oImg.onload = function () {
oGc.drawImage(oImg, 10, 10);
var imgData = oGc.getImageData(10, 10, 200, 200),
data = imgData.data, avg = 0;
for( var i = 0; i < data.length; i += 4 ) {
avg = ( data[i] + data[i+1] + data[i+2] ) / 3;
data[i] = avg;
data[i+1] = avg;
data[i+2] = avg;
}
//处理完之后,再次输出
oGc.putImageData( imgData, 220, 10 );
}
}
</script>
</head>
<body>
<canvas id="canvas" width="500" height="400"></canvas>
</body>
</html>

也可以分配rgb的灰度比例

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset='utf-8' />
<style>
#canvas {
border: 1px dashed #aaa;
}
</style>
<script>
window.onload = function () {
var oCanvas = document.querySelector("#canvas"),
oGc = oCanvas.getContext('2d'); var oImg = new Image();
oImg.src = './img/mv.jpg';
oImg.onload = function () {
oGc.drawImage(oImg, 10, 10);
var imgData = oGc.getImageData(10, 10, 200, 200),
data = imgData.data, avg = 0;
for( var i = 0; i < data.length; i += 4 ) {
avg = data[i] * 0.3 + data[i+1] * 0.3 + data[i+2] * 0.4;
data[i] = avg;
data[i+1] = avg;
data[i+2] = avg;
}
//处理完之后,再次输出
oGc.putImageData( imgData, 220, 10 );
}
}
</script>
</head>
<body>
<canvas id="canvas" width="500" height="400"></canvas>
</body>
</html>

三、调节亮度的强弱

在r、g、b、通道上加上一正值就是变亮,加上负值就是变暗

 var oImg = new Image();
oImg.src = './img/mv.jpg';
oImg.onload = function () {
oGc.drawImage(oImg, 10, 10);
var imgData = oGc.getImageData(10, 10, 200, 200),
data = imgData.data, avg = 0;
for( var i = 0; i < data.length; i += 4 ) {
data[i] += 30;
data[i+1] += 50;
data[i+2] += 50;
}
//处理完之后,再次输出
oGc.putImageData( imgData, 220, 10 );
}

变暗:

data[i] -= 30;
data[i+1] -= 50;
data[i+2] -= 50;

四、复古效果

将r, g, b按比例混合相加。

 var oImg = new Image();
oImg.src = './img/mv.jpg';
oImg.onload = function () {
oGc.drawImage(oImg, 10, 10);
var imgData = oGc.getImageData(10, 10, 200, 200),
data = imgData.data, avg = 0;
for( var i = 0; i < data.length; i += 4 ) {
r = data[i];
g = data[i+1];
b = data[i+2];
data[i] = r * 0.3 + g * 0.4 + b * 0.3;
data[i+1] = r * 0.2 + g * 0.6 + b * 0.2;
data[i+2] = r * 0.4 + g * 0.3 + b * 0.3;
}
//处理完之后,再次输出
oGc.putImageData( imgData, 220, 10 );
}

五、蓝色蒙版

蓝色 蒙版就是让图片偏蓝色,将蓝色通道赋值为 r, g, b三原色的平均值,把绿色,红色通道设置为0,其他蒙版效果,只要设置对应的通道平均值,关闭其他通道即可.

 var oImg = new Image();
oImg.src = './img/mv.jpg';
oImg.onload = function () {
oGc.drawImage(oImg, 10, 10);
var imgData = oGc.getImageData(10, 10, 200, 200),
data = imgData.data, avg = 0;
for( var i = 0; i < data.length; i += 4 ) {
avg = ( data[i] + data[i+1] + data[i+2] / 3 );
data[i] = 0;
data[i+1] = 0;
data[i+2] = avg;
}
//处理完之后,再次输出
oGc.putImageData( imgData, 220, 10 );
}

六、透明度

这个很简单,只要把透明度乘以一个0~1之间的值即可。跟css的opacity一样

 var oImg = new Image();
oImg.src = './img/mv.jpg';
oImg.onload = function () {
oGc.drawImage(oImg, 10, 10);
var imgData = oGc.getImageData(10, 10, 200, 200),
data = imgData.data, avg = 0;
for( var i = 0; i < data.length; i += 4 ) {
data[i+3] *= 0.2;
}
//处理完之后,再次输出
oGc.putImageData( imgData, 220, 10 );
}

七、createImageData:根据图片或者某个宽度与高度创建一个像素区域

cxt.createImageData( w, h )

cxt.createImageData( imgData )

w, h:创建区域的宽度与高度

imgData: 创建的区域与这个像素区域的宽度和高度相同,imgData就是通过getImageData获取到图片像素的 返回值

1,根据一个图片的宽度与高度,创建一个透明的红色像素区域

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset='utf-8' />
<style>
#canvas {
border: 1px dashed #aaa;
}
</style>
<script>
window.onload = function () {
var oCanvas = document.querySelector("#canvas"),
oGc = oCanvas.getContext('2d'); var oImg = new Image();
oImg.src = './img/mv.jpg';
oImg.onload = function () {
oGc.drawImage(oImg, 10, 10);
var imgData = oGc.getImageData(10, 10, 200, 200),
data = imgData.data,
imgData2 = oGc.createImageData( imgData ),
data2 = imgData2.data;
for( var i = 0; i < imgData2.width * imgData2.height * 4; i += 4 ) {
data2[i] = 255;
data2[i+1] = 0;
data2[i+2] = 0;
data2[i+3] = 30;
}
//处理完之后,再次输出
oGc.putImageData( imgData2, 220, 10 );
}
}
</script>
</head>
<body>
<canvas id="canvas" width="500" height="400"></canvas>
</body>
</html>

2,自定一个200 x 200的蓝色透明像素区域

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset='utf-8' />
<style>
#canvas {
border: 1px dashed #aaa;
}
</style>
<script>
window.onload = function () {
var oCanvas = document.querySelector("#canvas"),
oGc = oCanvas.getContext('2d'); var imgData = oGc.createImageData( 200, 200 ),
data = imgData.data;
for( var i = 0; i < imgData.width * imgData.height * 4 ; i += 4 ){
data[i] = 0;
data[i+1] = 0;
data[i+2] = 255;
data[i+3] = 100;
}
oGc.putImageData( imgData, 10, 10 );
}
</script>
</head>
<body>
<canvas id="canvas" width="500" height="400"></canvas>
</body>
</html>

[js高手之路] html5 canvas系列教程 - 像素操作(反色,黑白,亮度,复古,蒙版,透明)的更多相关文章

  1. [js高手之路] html5 canvas系列教程 - 图片操作(drawImage,clip,createPattern)

    接着上文[js高手之路] html5 canvas系列教程 - 文本样式(strokeText,fillText,measureText,textAlign,textBaseline)继续,本文介绍的 ...

  2. [js高手之路] html5 canvas系列教程 - 线形渐变,径向渐变与阴影设置

    接着上文[js高手之路] html5 canvas系列教程 - 像素操作(反色,黑白,亮度,复古,蒙版,透明)继续. 一.线形渐变 线形渐变指的是一条直线上发生的渐变. 用法: var linear ...

  3. [js高手之路] html5 canvas系列教程 - 状态详解(save与restore)

    本文内容与路径([js高手之路] html5 canvas系列教程 - 开始路径beginPath与关闭路径closePath详解)是canvas中比较重要的概念.掌握理解他们是做出复杂canvas动 ...

  4. [js高手之路] html5 canvas系列教程 - 掌握画直线图形的常用API

    我们接着上文[js高手之路] html5 canvase系列教程 - 认识canvas以及基本使用方法继续. 一.直线的绘制 cxt.moveTo( x1, y1 ): 将画笔移动到x1, y1这个点 ...

  5. [js高手之路] html5 canvas系列教程 - arcTo(弧度与二次,三次贝塞尔曲线以及在线工具)

    之前,我写了一个arc函数的用法:[js高手之路] html5 canvas系列教程 - arc绘制曲线图形(曲线,弧线,圆形). arcTo: cxt.arcTo( cx, cy, x2, y2, ...

  6. [js高手之路] html5 canvas系列教程 - arc绘制曲线图形(曲线,弧线,圆形)

    绘制曲线,经常会用到路径的知识,如果你对路径有疑问,可以参考我的这篇文章[js高手之路] html5 canvas系列教程 - 开始路径beginPath与关闭路径closePath详解. arc:画 ...

  7. [js高手之路] html5 canvas系列教程 - 文本样式(strokeText,fillText,measureText,textAlign,textBaseline)

    接着上文线条样式[js高手之路] html5 canvas系列教程 - 线条样式(lineWidth,lineCap,lineJoin,setLineDash)继续. canvas提供两种输出文本的方 ...

  8. [js高手之路] html5 canvas系列教程 - 线条样式(lineWidth,lineCap,lineJoin,setLineDash)

    上文,写完弧度与贝塞尔曲线[js高手之路] html5 canvas系列教程 - arcTo(弧度与二次,三次贝塞尔曲线以及在线工具),本文主要是关于线条的样式设置 lineWidth: 设置线条的宽 ...

  9. [js高手之路] html5 canvas动画教程 - 实时获取鼠标的当前坐标

    有了前面的canvas基础之后,现在开始就精彩了,后面写的canvas教程都是属于综合应用,前面已经写了常用的canvas基础知识,参考链接如下: [js高手之路] html5 canvas系列教程 ...

随机推荐

  1. python+selenium自动化软件测试(第13章):selenium面试题

    前言最近看到群里有小伙伴贴出一组面试题,最近又是跳槽黄金季节,小编忍不住抽出一点时间总结了下 一.selenium中如何判断元素是否存在?expected_conditions模块提供了16种判断方法 ...

  2. Java面试准备之探究集合

    摘要:之前虽然对集合框架一些知识点作了总结,但是想想面试可能会问源码,于是又大致研究了一下集合框架的一些实现类的源码,在此整理一下. 一.集合框架 二.深究实现类 1.ArrayList源码实现 Ar ...

  3. java线程锁

    一.synchronized         这货可以锁对象,锁变量,锁方法,锁代码,好像什么都能锁,缺点就是如果一个锁堵了,其他的只能等待忙并不能把当前的锁给释放.二. ReentrantLockR ...

  4. 服务端性能测试 TPS

     针对服务器端的性能,以TPS为主来衡量系统的性能,并发用户数为辅来衡量系统的性能,如果必须要用并发用户数来衡量的话,需要一个前提,那就是交易在多长时间内完成,因为在系统负载不高的情况下,将思考时间( ...

  5. lucene&solr-day1

        全文检索课程 Lucene&Solr(1) 1.   计划 第一天:Lucene的基础知识 1.案例分析:什么是全文检索,如何实现全文检索 2.Lucene实现全文检索的流程 a)   ...

  6. ThreadLoacl的反思

    在我的随笔 spring mvc:注解@ModelAttribue妙用  中使用ThreadLocal来简化spring mvc控制层controller中的ModelMap,Response.Jso ...

  7. 【Java IO流】对象的序列化和反序列化

    对象的序列化和反序列化 1)对象序列化,就是将Object对象转换成byte序列,反之叫对象的反序列化. 2)序列化流(ObjectOutputStream),是字节的过滤流—— writeObjec ...

  8. 从Object和Function说说JS的原型链

    ECMAScript规定了两个特殊的内置对象:Object和Function.他们的特殊性在于,他们本身既是对象又是函数,而他们同时也是对象和函数的构造器.这种自己生自己的逻辑显然违反人性,如果还停留 ...

  9. MySQL在高版本需要指明是否进行SSL连接问题

    Java使用mysql-jdbc连接MySQL出现如下警告: Establishing SSL connection without server's identity verification is ...

  10. 201521123061 《Java程序设计》第八周学习总结

    201521123061 <Java程序设计>第八周学习总结 1. 本周学习总结 2. 书面作业 1.List中指定元素的删除(题目4-1) 1.1 实验总结 主要是应用到了list中的a ...