canvas图像处理——实现滤镜效果

                                         实现滤镜效果

 

点击按钮出现不同滤镜效果

 

首先,我们分析滤镜的具体,主要就是对图片的每个具体像素进行处理,先拿到像素,处理后再将像素放回去。

 

1.怎样拿到像素

        通过getImageData可以拿到图片的imageData,imageData包含3个内容:width,height,data;

        width,height指的是图片的宽和高

       data指的是图片内部所有信息。

      context.getImageData(x, y, w, h),从x,y坐标处爬取图片宽为w,高为h

var imageData = cxta.getImageData(0, 0, canvasa.width, canvasa.height);
			var pixelData = imageData.data;

     获取图片data,将其存储在pixelData中。

    这里有一个问题就是本地图片使用getImageData方法的话会产生一个图片跨域的问题。

   解决方法1.使用服务器,将图片放在服务器中;

                  2.使用火狐浏览器

  

2.使用不同的滤镜算法

  我们在这个demo中使用了5个滤镜算法

  灰度滤镜:计算出图片每个像素点的灰度值

function grey(){
			var imageData = cxta.getImageData(0, 0, canvasa.width, canvasa.height);
			var pixelData = imageData.data;
			for (var i = 0; i < canvasb.width*canvasb.height; i++) {
				var r = pixelData[i*4+0]
				var g = pixelData[i*4+1]
				var b = pixelData[i*4+2]

				var grey = r*0.3+g*0.59+b*0.11//图片灰度值

				pixelData[i*4+0] = grey
				pixelData[i*4+1] = grey
				pixelData[i*4+2] = grey
			}
			cxtb.putImageData(imageData,0, 0, 0, 0, canvasb.width, canvasb.height)
		}

 

  黑白滤镜:图片中没有灰色,只有黑与白,灰度值大于255/2,则显示为黑色,否则为白色

 

function black(){//黑白滤镜即图片中没有灰色
			var imageData = cxta.getImageData(0, 0, canvasa.width, canvasa.height);
			var pixelData = imageData.data;
			for (var i = 0; i < canvasb.width*canvasb.height; i++) {
				var r = pixelData[i*4+0]
				var g = pixelData[i*4+1]
				var b = pixelData[i*4+2]

				var grey = r*0.3+g*0.59+b*0.11//图片灰度值

				if (grey >255/2) {
					v = 255
				}
				else{
					v = 0
				}

				pixelData[i*4+0] = v
				pixelData[i*4+1] = v
				pixelData[i*4+2] = v
			}
			cxtb.putImageData(imageData,0, 0, 0, 0, canvasb.width, canvasb.height)
		}

 

  反色滤镜:图片每个像素点的颜色变为原来颜色的255-原

 

function reverse(){//图片中每个像素的rgb都是255-原
			var imageData = cxta.getImageData(0, 0, canvasa.width, canvasa.height);
			var pixelData = imageData.data;
			for (var i = 0; i < canvasb.width*canvasb.height; i++) {
				var r = pixelData[i*4+0]
				var g = pixelData[i*4+1]
				var b = pixelData[i*4+2]

				pixelData[i*4+0] = 255-r
				pixelData[i*4+1] = 255-g
				pixelData[i*4+2] = 255-b
			}
			cxtb.putImageData(imageData,0, 0, 0, 0, canvasb.width, canvasb.height)
		}

 

  模糊滤镜:计算一个像素点及其周围像素点的平均值

 

function blur(){//要参考周围的像素
			var imageData = cxta.getImageData(0, 0, canvasa.width, canvasa.height);
			var pixelData = imageData.data;
			

			//创建作为参考的像素
			var tmpImageData = cxta.getImageData(0, 0, canvasa.width, canvasa.height);
			var tmpPixelData = tmpImageData.data;

			var blurR = 3
			var totalnum = (2*blurR+1)*(2*blurR+1)
			//此处循环需从1开始,..-1结束,否则在里面的二层循环(dx=-1,dy=-1)就会越界
			for (var i = blurR; i < canvasb.height-blurR; i++) {
				for (var j = blurR; j < canvasb.width-blurR; j++) {

					var totalr = 0,totalg = 0,totalb = 0;

					//一个像素点周围的加上自身
					for (var dx = -blurR; dx <= blurR; dx++) {
						for(var dy = -blurR; dy<=blurR; dy++){
							var x = i+dx;
							var y = j+dy;

							var p = x*canvasb.width+y
							totalr += tmpPixelData[p*4+0]
							totalg += tmpPixelData[p*4+1]
							totalb += tmpPixelData[p*4+2]
						}
					}
					var p = i*canvasb.width+j//每个像素点

					pixelData[p*4+0] = totalr/totalnum
					pixelData[p*4+1] = totalg/totalnum
					pixelData[p*4+2] = totalb/totalnum

				}
			}

			cxtb.putImageData(imageData,0, 0, 0, 0, canvasb.width, canvasb.height)
		}

 

  马赛克滤镜:和模糊滤镜类似,只是马赛克滤镜是计算每一块的平均值,在这里,需要计算图片的宽与高来确定方块的边长

                      如代码中:var size = 25,因为我用的图片是500*375的,25可以整除。

 

function mosaic(){//要参考周围的像素
			var imageData = cxta.getImageData(0, 0, canvasa.width, canvasa.height);
			var pixelData = imageData.data;
			

			//创建作为参考的像素
			var tmpImageData = cxta.getImageData(0, 0, canvasa.width, canvasa.height);
			var tmpPixelData = tmpImageData.data;

			var size = 25//马赛克方块的边长
			var totalnum = size*size
			//此处循环需从1开始,..-1结束,否则在里面的二层循环(dx=-1,dy=-1)就会越界
			for (var i = 0; i < canvasb.height; i+=size) {
				for (var j = 0; j < canvasb.width; j+=size) {

					var totalr = 0,totalg = 0,totalb = 0;

					//一个像素点周围的加上自身
					for (var dx = 0; dx < size; dx++) {
						for(var dy = 0; dy

 

3.将处理后的像素点放回图片中

           放置imageData
      context.putImageData(imageData, dx, dy, dirtyX, dirtyY, dirtyW, dirtyH)
      dx,dy在画布上的初始偏移

 

 

总体效果:

 

 

所有代码如下:

 




	
	滤镜练习


	

 

你可能感兴趣的:(canvas)