zoukankan      html  css  js  c++  java
  • Javascript图像处理

    思路

    HTML5的canvas提供了getImageData接口来获取canvas中的数据,所以我们能够先用drawImage接口将图片画在canvas上然后再通过getImageData得到图片数据矩阵。

    canvas的浏览器支持情况,请参见:

    http://html5test.com/compare/feature/canvas-context.html

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

    http://html5test.com/compare/feature/webgl-datatypes-ArrayBuffer.html

    基本矩阵

    在图像处理中,矩阵计算是非常重要的内容,所以我们首先来建立一个矩阵模型。

    通过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 = 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);

    例子

    http://www.w3schools.com/tags/playcanvas.asp?filename=playcanvas_drawimagedy&preval=img,90,130,50,60,10,10,50,60

    还有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];

    http://www.w3schools.com/tags/tryit.asp?filename=tryhtml5_canvas_getimagedata_firstpx

    矩阵转成图像数据的方法

    经过处理后的矩阵,需要一个方法变成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图像处理系列

    参考资料

    HTML Canvas Reference

    Miscellaneous Image Transformations

  • 相关阅读:
    探索事务日志与恢复模式(1-13)
    sql server 复制、镜像常见故障处理
    (3.2)mysqldump之备份单个表及脚本批量备份
    Log Explorer 恢复误删除、更新数据
    ApexSQL Log 从意外UPDATE和DELETE操作中恢复SQL Server数据
    ApexSQL Recover 恢复一个被drop的表的数据
    数据库参数调优--自动更新统计信息
    T-SQL利用笛卡尔积/窗口函数_分析函数/表连接累计、累加
    【生产问题】-dbcc checkdb报错-数据页故障
    (4.4)dbcc checkdb 数据页修复
  • 原文地址:https://www.cnblogs.com/justany/p/2831945.html
Copyright © 2011-2022 走看看