Javascript图像处理思路及实现代码

 更新时间:2012年12月25日 14:08:14   作者:  
HTML5的canvas提供了getImageData接口来获取canvas中的数据,所以我们能够先用drawImage接口将图片画在canvas上然后再通过getImageData得到图片数据矩阵,需要了解的朋友可以详细参考下
思路
HTML5的canvas提供了getImageData接口来获取canvas中的数据,所以我们能够先用drawImage接口将图片画在canvas上然后再通过getImageData得到图片数据矩阵。

需要注意,虽然IE9开始支持了canvas接口,但是其getImageData获取的数据并不是以标准的TypedArray方式存储的,或者说IE9没有提供对WebGL Native binary data的支持,所以如果需要对IE9支持,下面的矩阵需要用Array的方式保存。虽然IE9以下版本(例如IE8)有开源项目explorercanvas提供canvas支持,但很可惜G_vmlCanvasManager并没有提供位图数据获取接口。TypedArray的相关内容可以参考HTML5的新数组

基本矩阵
在图像处理中,矩阵计算是非常重要的内容,所以我们首先来建立一个矩阵模型。
通过getImageData接口获取的ImageData虽然具有类似矩阵的结构,但是他的结构是不可变的,不适合扩展,所以我们选择在Javascript中自建一个矩阵。
复制代码 代码如下:

function Mat(__row, __col, __data, __buffer){
this.row = __row || 0;
this.col = __col || 0;
this.channel = 4;
this.buffer = __buffer || new ArrayBuffer(__row * __col * 4);
this.data = new Uint8ClampedArray(this.buffer);
__data && this.data.set(__data);
this.bytes = 1;
this.type = "CV_RGBA";
}

row - 代表矩阵的行数
col - 代表矩阵的列数
channel - 代表通道数量,因为通过getImageData获取的图片数据是以RGBA色彩空间进行描述的,即有Red(红)、Green(绿)、Blue(蓝)和Alpha(不透明度)四个通道。
buffer - 数据所用的ArrayBuffer引用。
data - 图片的Uint8ClampedArray数组数据。
bytes - 每个数据单位占用字节,因为是uint8数据类型,所以占用字节数为1。
type - 数据类型是CV_RGBA。
图片数据转成矩阵的方法
复制代码 代码如下:

function imread(__image){
var width = __image.width,
height = __image.height;
iResize(width, height);
iCtx.drawImage(__image, 0, 0);
var imageData = iCtx.getImageData(0, 0, width, height),
tempMat = new Mat(height, width, imageData.data);
imageData = null;
iCtx.clearRect(0, 0, width, height);
return tempMat;
}

注意:这里的__image指的是Image对象,不是字符串URL。因为浏览器中Image的读取是一个异步过程,并不能立刻返回相应的Mat对象,所以这个函数应当这样使用:
复制代码 代码如下:

var img = new Image();
img.onload = function(){
var myMat = cv.imread(img);
};
img.src = "1.jpg";

iCtx和iResize方法是一个全局变量,允许给其它函数公用:
复制代码 代码如下:

var iCanvas = document.createElement("canvas"),
iCtx = iCanvas.getContext("2d");
function iResize(__width, __height){
iCanvas.width = __width;
iCanvas.height = __height;
}

我们来看一下drawImage方法
用途
在canvas上绘制一个图片。
语法
context.drawImage(img,x,y);
context.drawImage(img,x,y,width,height);
context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height);
例子
还有getImageData方法:
用途
获取canvas中的图像数据。
数据是以RGBA色彩空间返回的,即:
R - 红色通道大小
G - 绿色通道大小
B - 蓝色通道大小
A - 不透明程度大小
语法
context.getImageData(x,y,width,height);
例子
复制代码 代码如下:

red = imgData.data[0];
green = imgData.data[1];
blue = imgData.data[2];
alpha = imgData.data[3];

矩阵转成图像数据的方法
经过处理后的矩阵,需要一个方法变成ImageData,然后我们就可以通过putImageData方法,在canvas上绘制经过处理的图像了。
复制代码 代码如下:

function RGBA2ImageData(__imgMat){
var width = __imgMat.col,
height = __imgMat.row,
imageData = iCtx.createImageData(width, height);
imageData.data.set(__imgMat.data);
return imageData;
}

我们来看一下putImageData方法
用途
通过图像数据,在canvas上绘制图像。
语法
context.putImageData(imgData,x,y,dirtyX,dirtyY,dirtyWidth,dirtyHeight);
将彩色图转换成灰度图
最后我们进行一个简单的色彩空间变换,将图像从RGBA转成GRAY。
复制代码 代码如下:

function cvtColor(__src){
if(__src.type && __src.type === "CV_RGBA"){
var row = __src.row,
col = __src.col;
var dst = new Mat(row, col);
data = dst.data,
data2 = __src.data;
var pix1, pix2, pix = __src.row * __src.col * 4;
while (pix){
data[pix -= 4] = data[pix1 = pix + 1] = data[pix2 = pix + 2] = (data2[pix] * 299 + data2[pix1] * 587 + data2[pix2] * 114) / 1000;
data[pix + 3] = data2[pix + 3];
}
}else{
return src;
}
return dst;
}

参考OpenCV文档中的转换公式
RGBA to Gray: Y <- 0.299 * R + 0.587 * G + 0.114 * B
Gray to RGBA: R <- Y, G <- Y, B <- Y, A <- 255
我们可以得出RGBA to GRAY(指的是拥有4个通道)对应映射关系应该为:
RGBA to RGBA(GRAY): R1 = G1 = B1 <- 0.299 * R + 0.587 * G + 0.114 * B , A1 <- A

相关文章

  • 基于JavaScript制作霓虹灯文字 代码 特效

    基于JavaScript制作霓虹灯文字 代码 特效

    这里使用JS实现网页上的霓虹灯文字特效代码特效,运行效果看一下,你会看到文字的颜色像霓虹灯一样,连续不停变化,五颜六色的,很炫的样子,所以就叫做霓虹文字,也可以叫他文字变色效果,下面跟着小编一起学习JavaScript制作霓虹灯文字 代码特效,需要的朋友一起学习吧
    2015-09-09
  • Java中int与integer的区别(基本数据类型与引用数据类型)

    Java中int与integer的区别(基本数据类型与引用数据类型)

    这篇文章主要介绍了int与integer的区别(基本数据类型与引用数据类型),简单的说 int 是基本数据类型,integer 是引用数据类型,具体区别详解大家参考下本文
    2017-02-02
  • Bootstrap CSS布局之代码

    Bootstrap CSS布局之代码

    这篇文章主要介绍了Bootstrap CSS布局之代码的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-12-12
  • JS逆向之爱奇艺滑块加密的实现

    JS逆向之爱奇艺滑块加密的实现

    本文主要介绍了JS逆向之爱奇艺滑块加密的实现,文中根据实例编码详细介绍的十分详尽,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • JavaScript数组操作学习之splice()函数入门与精通

    JavaScript数组操作学习之splice()函数入门与精通

    这篇文章介绍了JavaScript数组操作中的splice()方法,详细讲解了其定义、语法和用法,并通过实例展示了如何使用该方法进行数组元素的添加、删除和替换,需要的朋友可以参考下
    2024-11-11
  • go.js的基本使用方法详解【与vue,react同理】

    go.js的基本使用方法详解【与vue,react同理】

    这篇文章主要介绍了go.js的基本使用方法,结合实例形式详细分析了go.js基本功能、原理及vue中使用方法,需要的朋友可以参考下
    2023-06-06
  • 详解JavaScript的数据类型以及数据类型的转换

    详解JavaScript的数据类型以及数据类型的转换

    这篇文章主要介绍了JavaScript的数据类型以及数据类型的转换,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-04-04
  • JavaScript学习笔记之DOM基础操作实例小结

    JavaScript学习笔记之DOM基础操作实例小结

    这篇文章主要介绍了JavaScript学习笔记之DOM基础操作,结合实例形式总结分析了javascript针对dom元素节点、属性的相关获取、设置等操作技巧,需要的朋友可以参考下
    2019-01-01
  • JavaScript实现函数重载的代码示例

    JavaScript实现函数重载的代码示例

    在JavaScript中并没有直接支持函数重载的机制,但是可以通过一些技巧来模拟函数重载的效果,比如使用参数判断,使用默认参数,对象参数,这些方法都可以实现类似函数重载的效果,所以本文就给大家介绍一下JavaScript如何实现函数重载,需要的朋友可以参考下
    2023-08-08
  • 如何用JavaScript检测当前浏览器是无头浏览器

    如何用JavaScript检测当前浏览器是无头浏览器

    这篇文章主要介绍了如何用JavaScript检测当前浏览器是无头浏览器,对无头浏览器感兴趣的同学,可以参考一下
    2021-04-04

最新评论