html5canvas渐变讲解(纯JavaScript实现HTML5Canvas6种特效滤镜)
html5canvas渐变讲解(纯JavaScript实现HTML5Canvas6种特效滤镜)6.合理5.雕刻2.灰色调3.模糊4.浮雕
作者:前端Q
转发链接:https://mp.weixin.qq.com/s/ewFfXptccFs5KvjUINLGbQ
前端小试牛刀,实现了六款简单常见html5 canvas特效滤镜,并且封装成一个纯JavaScript可调用的API文件gloomyfishfilter.js。支持的特效滤镜分别为:
1.反色
2.灰色调
3.模糊
4.浮雕
5.雕刻
6.合理
滤镜原理解释:2.灰色调:获取一个预期点RGB值r,g,b则新的RGB值
newr =(r * 0.272) (g * 0.534) (b * 0.131);
newg =(r * 0.349) (g * 0.686) (b * 0.168);
newb =(r * 0.393) (g * 0.769) (b * 0.189);
3.模糊:基于一个5 * 5的卷积核
4.浮雕与雕刻:
根据当前预期的前一个预期RGB值与它的后一个重新的RGB值之差再加上128
5.总体:模拟了物体在镜子中与之对应的效果。
杂项准备1、如何获取Canvas 2d context对象var canvas = document.getElementById("target");
canvas.width = source.clientWidth;
canvas.height = source.clientHeight;
**if**(!canvas.getContext) {
console.log("Canvas not supported. Please install a HTML5compatible browser.");
**return**;
}
// get 2D context of canvas and draw image
tempContext = canvas.getContext("2d");
2、如何添加一个DOM img对象到Canvas对象中
var source = document.getElementById("source");
tempContext.drawImage(source 0 0 canvas.width canvas.height);
3、如何从Canvas对象中获取预定数据
var canvas = document.getElementById("target");
var len = canvas.width * canvas.height * 4;
var canvasData = tempContext.getImageData(0 0 canvas.width canvas.height);
var binaryData = canvasData.data;
4、如何对DOM对象实现鼠标ClickEvent绑定
function bindButtonEvent(element type handler)
{
if(element.addEventListener){
element.addEventListener(type handler **false**);
}else{
element.attachEvent('on' type handler);// for IE6 7 8
}
}
5、如何调用实现的gfilter API完成滤镜功能
<scriptsrc=*"gloomyfishfilter.js"*></script> //导入API文件
gfilter.colorInvertProcess(binaryData len); //调用 API
6、浏览器支持:IE,FF,Chrome上测试通过,其中IE上支持通过以下标签实现:
<meta http-equiv="X-UA-Compatible"*content=*"chrome=IE8">
效果演示:
CSS部分:
#svgContainer {
width:800px;
height:600px;
background-color:#EEEEEE;
}
#sourceDiv { float: left; border: 2px solid blue}
#targetDiv { float: right;border: 2px solid red}
filter1.html中HTML源代码:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="chrome=IE8">
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
<title>Canvas Filter Demo</title>
<link href="default.css" rel="stylesheet" />
<script src="gloomyfishfilter.js"></scrip>
</head>
<body>
<h1>HTML Canvas Image Process - By Gloomy Fish</h1>
<div id="svgContainer">
<div id="sourceDiv">
<img id="source" src="../test.png" />
</div>
<div id="targetDiv">
<canvas id="target"></canvas>
</div>
</div>
<div id="btn-group">
<button type="button" id="invert-button">反色</button>
<button type="button" id="adjust-button">灰色调</button>
<button type="button" id="blur-button">模糊</button>
<button type="button" id="relief-button">浮雕</button>
<button type="button" id="diaoke-button">雕刻</button>
<button type="button" id="mirror-button">镜像</button>
</div>
</body>
</html>
filter1.html中JavaScript源代码:
var tempContext = null; // global variable 2d context
window.onload = function() {
var source = document.getElementById("source");
var canvas = document.getElementById("target");
canvas.width = source.clientWidth;
canvas.height = source.clientHeight;
if (!canvas.getContext) {
console.log("Canvas not supported. Please install a HTML5 compatible browser.");
return;
}
// get 2D context of canvas and draw image
tempContext = canvas.getContext("2d");
tempContext.drawImage(source 0 0 canvas.width canvas.height);
// initialization actions
var inButton = document.getElementById("invert-button");
var adButton = document.getElementById("adjust-button");
var blurButton = document.getElementById("blur-button");
var reButton = document.getElementById("relief-button");
var dkButton = document.getElementById("diaoke-button");
var mirrorButton = document.getElementById("mirror-button");
// bind mouse click event
bindButtonEvent(inButton "click" invertColor);
bindButtonEvent(adButton "click" adjustColor);
bindButtonEvent(blurButton "click" blurImage);
bindButtonEvent(reButton "click" fudiaoImage);
bindButtonEvent(dkButton "click" kediaoImage);
bindButtonEvent(mirrorButton "click" mirrorImage);
}
function bindButtonEvent(element type handler)
{
if(element.addEventListener) {
element.addEventListener(type handler false);
} else {
element.attachEvent('on' type handler); // for IE6 7 8
}
}
function invertColor() {
var canvas = document.getElementById("target");
var len = canvas.width * canvas.height * 4;
var canvasData = tempContext.getImageData(0 0 canvas.width canvas.height);
var binaryData = canvasData.data;
// Processing all the pixels
gfilter.colorInvertProcess(binaryData len);
// Copying back canvas data to canvas
tempContext.putImageData(canvasData 0 0);
}
function adjustColor() {
var canvas = document.getElementById("target");
var len = canvas.width * canvas.height * 4;
var canvasData = tempContext.getImageData(0 0 canvas.width canvas.height);
var binaryData = canvasData.data;
// Processing all the pixels
gfilter.colorAdjustProcess(binaryData len);
// Copying back canvas data to canvas
tempContext.putImageData(canvasData 0 0);
}
function blurImage()
{
var canvas = document.getElementById("target");
var len = canvas.width * canvas.height * 4;
var canvasData = tempContext.getImageData(0 0 canvas.width canvas.height);
// Processing all the pixels
gfilter.blurProcess(tempContext canvasData);
// Copying back canvas data to canvas
tempContext.putImageData(canvasData 0 0);
}
function fudiaoImage()
{
var canvas = document.getElementById("target");
var len = canvas.width * canvas.height * 4;
var canvasData = tempContext.getImageData(0 0 canvas.width canvas.height);
// Processing all the pixels
gfilter.reliefProcess(tempContext canvasData);
// Copying back canvas data to canvas
tempContext.putImageData(canvasData 0 0);
}
function kediaoImage()
{
var canvas = document.getElementById("target");
var len = canvas.width * canvas.height * 4;
var canvasData = tempContext.getImageData(0 0 canvas.width canvas.height);
// Processing all the pixels
gfilter.diaokeProcess(tempContext canvasData);
// Copying back canvas data to canvas
tempContext.putImageData(canvasData 0 0);
}
function mirrorImage()
{
var canvas = document.getElementById("target");
var len = canvas.width * canvas.height * 4;
var canvasData = tempContext.getImageData(0 0 canvas.width canvas.height);
// Processing all the pixels
gfilter.mirrorProcess(tempContext canvasData);
// Copying back canvas data to canvas
tempContext.putImageData(canvasData 0 0);
}
滤镜源代码(gloomyfishfilter.js):
var gfilter = {
type: "canvas"
name: "filters"
author: "zhigang"
getInfo: function () {
return this.author ' ' this.type ' ' this.name;
}
/**
* invert color value of pixel new pixel = RGB(255-r 255-g 255 - b)
*
* @param binaryData - canvas's imagedata.data
* @param l - length of data (width * height of image data)
*/
colorInvertProcess: function(binaryData l) {
for (var i = 0; i < l; i = 4) {
var r = binaryData[i];
var g = binaryData[i 1];
var b = binaryData[i 2];
binaryData[i] = 255-r;
binaryData[i 1] = 255-g;
binaryData[i 2] = 255-b;
}
}
/**
* adjust color values and make it more darker and gray...
*
* @param binaryData
* @param l
*/
colorAdjustProcess: function(binaryData l) {
for (var i = 0; i < l; i = 4) {
var r = binaryData[i];
var g = binaryData[i 1];
var b = binaryData[i 2];
binaryData[i] = (r * 0.272) (g * 0.534) (b * 0.131);
binaryData[i 1] = (r * 0.349) (g * 0.686) (b * 0.168);
binaryData[i 2] = (r * 0.393) (g * 0.769) (b * 0.189);
}
}
/**
* deep clone image data of canvas
*
* @param context
* @param src
* @returns
*/
copyImageData: function(context src)
{
var dst = context.createImageData(src.width src.height);
dst.data.set(src.data);
return dst;
}
/**
* convolution - keneral size 5*5 - blur effect filter(模糊效果)
*
* @param context
* @param canvasData
*/
blurProcess: function(context canvasData) {
console.log("Canvas Filter - blur process");
var tempCanvasData = this.copyImageData(context canvasData);
var sumred = 0.0 sumgreen = 0.0 sumblue = 0.0;
for ( var x = 0; x < tempCanvasData.width; x ) {
for ( var y = 0; y < tempCanvasData.height; y ) {
// Index of the pixel in the array
var idx = (x y * tempCanvasData.width) * 4;
for(var subCol=-2; subCol<=2; subCol ) {
var colOff = subCol x;
if(colOff <0 || colOff >= tempCanvasData.width) {
colOff = 0;
}
for(var subRow=-2; subRow<=2; subRow ) {
var rowOff = subRow y;
if(rowOff < 0 || rowOff >= tempCanvasData.height) {
rowOff = 0;
}
var idx2 = (colOff rowOff * tempCanvasData.width) * 4;
var r = tempCanvasData.data[idx2 0];
var g = tempCanvasData.data[idx2 1];
var b = tempCanvasData.data[idx2 2];
sumred = r;
sumgreen = g;
sumblue = b;
}
}
// calculate new RGB value
var nr = (sumred / 25.0);
var ng = (sumgreen / 25.0);
var nb = (sumblue / 25.0);
// clear previous for next pixel point
sumred = 0.0;
sumgreen = 0.0;
sumblue = 0.0;
// assign new pixel value
canvasData.data[idx 0] = nr; // Red channel
canvasData.data[idx 1] = ng; // Green channel
canvasData.data[idx 2] = nb; // Blue channel
canvasData.data[idx 3] = 255; // Alpha channel
}
}
}
/**
* after pixel value - before pixel value 128
* 浮雕效果
*/
reliefProcess: function(context canvasData) {
console.log("Canvas Filter - relief process");
var tempCanvasData = this.copyImageData(context canvasData);
for ( var x = 1; x < tempCanvasData.width-1; x )
{
for ( var y = 1; y < tempCanvasData.height-1; y )
{
// Index of the pixel in the array
var idx = (x y * tempCanvasData.width) * 4;
var bidx = ((x-1) y * tempCanvasData.width) * 4;
var aidx = ((x 1) y * tempCanvasData.width) * 4;
// calculate new RGB value
var nr = tempCanvasData.data[aidx 0] - tempCanvasData.data[bidx 0] 128;
var ng = tempCanvasData.data[aidx 1] - tempCanvasData.data[bidx 1] 128;
var nb = tempCanvasData.data[aidx 2] - tempCanvasData.data[bidx 2] 128;
nr = (nr < 0) ? 0 : ((nr >255) ? 255 : nr);
ng = (ng < 0) ? 0 : ((ng >255) ? 255 : ng);
nb = (nb < 0) ? 0 : ((nb >255) ? 255 : nb);
// assign new pixel value
canvasData.data[idx 0] = nr; // Red channel
canvasData.data[idx 1] = ng; // Green channel
canvasData.data[idx 2] = nb; // Blue channel
canvasData.data[idx 3] = 255; // Alpha channel
}
}
}
/**
* before pixel value - after pixel value 128
* 雕刻效果
*
* @param canvasData
*/
diaokeProcess: function(context canvasData) {
console.log("Canvas Filter - process");
var tempCanvasData = this.copyImageData(context canvasData);
for ( var x = 1; x < tempCanvasData.width-1; x )
{
for ( var y = 1; y < tempCanvasData.height-1; y )
{
// Index of the pixel in the array
var idx = (x y * tempCanvasData.width) * 4;
var bidx = ((x-1) y * tempCanvasData.width) * 4;
var aidx = ((x 1) y * tempCanvasData.width) * 4;
// calculate new RGB value
var nr = tempCanvasData.data[bidx 0] - tempCanvasData.data[aidx 0] 128;
var ng = tempCanvasData.data[bidx 1] - tempCanvasData.data[aidx 1] 128;
var nb = tempCanvasData.data[bidx 2] - tempCanvasData.data[aidx 2] 128;
nr = (nr < 0) ? 0 : ((nr >255) ? 255 : nr);
ng = (ng < 0) ? 0 : ((ng >255) ? 255 : ng);
nb = (nb < 0) ? 0 : ((nb >255) ? 255 : nb);
// assign new pixel value
canvasData.data[idx 0] = nr; // Red channel
canvasData.data[idx 1] = ng; // Green channel
canvasData.data[idx 2] = nb; // Blue channel
canvasData.data[idx 3] = 255; // Alpha channel
}
}
}
/**
* mirror reflect
*
* @param context
* @param canvasData
*/
mirrorProcess : function(context canvasData) {
console.log("Canvas Filter - process");
var tempCanvasData = this.copyImageData(context canvasData);
for ( var x = 0; x < tempCanvasData.width; x ) // column
{
for ( var y = 0; y < tempCanvasData.height; y ) // row
{
// Index of the pixel in the array
var idx = (x y * tempCanvasData.width) * 4;
var midx = (((tempCanvasData.width -1) - x) y * tempCanvasData.width) * 4;
// assign new pixel value
canvasData.data[midx 0] = tempCanvasData.data[idx 0]; // Red channel
canvasData.data[midx 1] = tempCanvasData.data[idx 1]; ; // Green channel
canvasData.data[midx 2] = tempCanvasData.data[idx 2]; ; // Blue channel
canvasData.data[midx 3] = 255; // Alpha channel
}
}
}
};
总结
感谢阅读,如果你觉得我今天分享的内容,不错,请点一个赞,谢谢!!