zoukankan      html  css  js  c++  java
  • Javascript图像处理之虚拟边缘

      原理来自Justany_WhiteSnowJavascript图像处理——虚拟边缘一文。  

    /*
     * BORDER_REPLICATE:     aaaaaaaa|abcdefgh|hhhhhhhh
     * BORDER_REFLECT:       hgfedcba|abcdefgh|hgfedcba
     * BORDER_REFLECT_101:   hgfedcb|abcdefgh|gfedcba
     * BORDER_WRAP:          efgh|abcdefgh|abcd
     * BORDER_CONSTANT:      iiiiiiii|abcdefgh|iiiiiiii  with some specified 'i'(default value [0, 0, 0, 255])
    */
    
    (function () {
        function imageVariousBorder(iCanvas, url, borderType, orientation, value) {
            this.canvas = iCanvas;
            this.iCtx = this.canvas.getContext("2d");
            this.url = url;
            this.borderType = borderType;
            this.orientation = orientation || "bottom";
            this.value = value || [0, 0, 0, 255];
        }
    
        imageVariousBorder.prototype = {
            imread: function (_image) {
                var width = _image.width,
                    height = _image.height;
                this.iResize(width, height);
                this.iCtx.drawImage(_image, 0, 0);
                var imageData = this.iCtx.getImageData(0, 0, width, height),
                    tempMat = new Mat(height, width, imageData.data);
                imageData = null;
                this.iCtx.clearRect(0, 0, width, height);
                return tempMat;
            },
            iResize: function (_width, _height) {
                this.canvas.width = _width;
                this.canvas.height = _height;
            },
            RGBA2ImageData: function (_imgMat) {
                var width = _imgMat.col,
                    height = _imgMat.row;
                var imageData = this.iCtx.createImageData(width, height);
                imageData.data.set(_imgMat.data);
                return imageData;
            },
            render: function () {
                var img = new Image();
                var _this = this;
                img.onload = function () {
                    var myMat = _this.imread(img);
                    var width = myMat.col;
                    var height = myMat.row;
                    if (_this.borderType == "BORDER_WRAP") {
                        width = width/2;
                        height = height/2;
                    }
                    var strOrientation = {
                        "left": [0, width, 0, 0],
                        "right": [0, 0, 0, width],
                        "bottom": [0, 0, height, 0],
                        "top": [height, 0, 0, 0],
                        "left_right": [0, width, 0, width]
                    };
                    var newImage = copyMakeBorder(myMat,
                        strOrientation[_this.orientation][0],
                        strOrientation[_this.orientation][1],
                        strOrientation[_this.orientation][2],
                        strOrientation[_this.orientation][3],
                        _this.borderType,
                        _this.value);
                    var newIamgeData = _this.RGBA2ImageData(newImage);
                    var newWidth = newImage.col;
                    var newHeight = newImage.row;
                    _this.iResize(newWidth, newHeight);
                    _this.iCtx.putImageData(newIamgeData, 0, 0);
                };
                img.src = this.url;
            }
        };
    
        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";
        }
    
        function copyMakeBorder(_src, _top, _left, _bottom, _right, _borderType, _value) {
            if (_src.type != "CV_RGBA") {
                console.log("not support this type");
            } else if (_borderType == "BORDER_CONSTANT") {
                return copyMakeConstBorder_8U(_src, _top, _left, _bottom, _right, _value);
            } else {
                return copyMakeBorder_8U(_src, _top, _left, _bottom, _right, _borderType);
            }
        }
    
        function borderInterpolate(_p, _len, _borderType) {
            if (_p < 0 || _p >= _len) {
                switch (_borderType) {
                    case "BORDER_REPLICATE":
                        _p = _p < 0 ? 0 : _len - 1;
                        break;
                    case "BORDER_REFLECT":
                    case "BORDER_REFLECT_101":
                        var delta = (_borderType == "BORDER_REFLECT_101");
                        if (_len == 1) {
                            return 0;
                        }
                        do {
                            if (_p < 0) {
                                _p = -_p - 1 + delta;
                            } else {
                                _p = _len - 1 - (_p - _len) - delta;
                            }
                        } while (_p < 0 || _p >= _len);
                        break;
                    case "BORDER_WRAP":
                        if (_p < 0) {
                            _p -= ((_p - _len + 1) / _len | 0) * _len;
                        }
                        if (_p >= _len) {
                            _p %= _len;
                        }
                        break;
                    case "BORDER_CONSTANT":
                        _p = -1;
                    default:
                        console.log(arguments.callee, "UNSPPORT_BORDER_TYPE");
                }
            }
            return _p;
        }
    
        function copyMakeBorder_8U(_src, _top, _left, _bottom, _right, _borderType) {
            var i, j;
            var width = _src.col,
                height = _src.row;
            var top = _top,
                left = _left || _top,
                right = _right || left,
                bottom = _bottom || top,
                dstWidth = width + left + right,
                dstHeight = height + top + bottom,
                borderType = _borderType || "BORDER_REFLECT";
            var buffer = new ArrayBuffer(dstHeight * dstWidth * 4),
                tab = new Uint32Array(left + right);
    
            for (i = 0; i < left; i++) {
                tab[i] = borderInterpolate(i - left, width, borderType);
            }
            for (i = 0; i < right; i++) {
                tab[i + left] = borderInterpolate(width + i, width, borderType);
            }
    
            var tempArray, data;
    
            for (i = 0; i < height; i++) {
                tempArray = new Uint32Array(buffer, (i + top) * dstWidth * 4, dstWidth);
                data = new Uint32Array(_src.buffer, i * width * 4, width);
                for (j = 0; j < left; j++)
                    tempArray[j] = data[tab[j]];
                for (j = 0; j < right; j++)
                    tempArray[j + width + left] = data[tab[j + left]];
                tempArray.set(data, left);
            }
    
            var allArray = new Uint32Array(buffer);
            for (i = 0; i < top; i++) {
                j = borderInterpolate(i - top, height, _borderType);
                tempArray = new Uint32Array(buffer, i * dstWidth * 4, dstWidth);
                tempArray.set(allArray.subarray((j + top) * dstWidth, (j + top + 1) * dstWidth));
            }
            for (i = 0; i < bottom; i++) {
                j = borderInterpolate(i + height, height, borderType);
                tempArray = new Uint32Array(buffer, (i + top + height) * dstWidth * 4, dstWidth);
                tempArray.set(allArray.subarray((j + top) * dstWidth, (j + top + 1) * dstWidth));
            }
    
            return new Mat(dstHeight, dstWidth, new Uint8ClampedArray(buffer));
        }
    
        function copyMakeConstBorder_8U(_src, _top, _left, _bottom, _right, _value) {
            var i, j;
            var width = _src.col,
                height = _src.row;
            var top = _top,
                left = _left || _top,
                right = _right || left,
                bottom = _bottom || top,
                dstWidth = width + left + right,
                dstHeight = height + top + bottom,
                value = _value || [0, 0, 0, 255];
            var constBuf = new ArrayBuffer(dstWidth * 4),
                constArray = new Uint8ClampedArray(constBuf);
            buffer = new ArrayBuffer(dstHeight * dstWidth * 4);
    
            for (i = 0; i < dstWidth; i++) {
                for (j = 0; j < 4; j++) {
                    constArray[i * 4 + j] = value[j];
                }
            }
    
            constArray = new Uint32Array(constBuf);
            var tempArray;
    
            for (i = 0; i < height; i++) {
                tempArray = new Uint32Array(buffer, (i + top) * dstWidth * 4, left);
                tempArray.set(constArray.subarray(0, left));
                tempArray = new Uint32Array(buffer, ((i + top + 1) * dstWidth - right) * 4, right);
                tempArray.set(constArray.subarray(0, right));
                tempArray = new Uint32Array(buffer, ((i + top) * dstWidth + left) * 4, width);
                tempArray.set(new Uint32Array(_src.buffer, i * width * 4, width));
            }
    
            for (i = 0; i < top; i++) {
                tempArray = new Uint32Array(buffer, i * dstWidth * 4, dstWidth);
                tempArray.set(constArray);
            }
    
            for (i = 0; i < bottom; i++) {
                tempArray = new Uint32Array(buffer, (i + top + height) * dstWidth * 4, dstWidth);
                tempArray.set(constArray);
            }
    
            return new Mat(dstHeight, dstWidth, new Uint8ClampedArray(buffer));
        }
    
        window.imageVariousBorder = imageVariousBorder;
    })();

      调用示例:

    var iCanvas = document.getElementById("variousBorder_replicate");
    var imgVariousBorder = new imageVariousBorder(iCanvas, "images/1.jpg", "BORDER_REPLICATE", "right");
    imgVariousBorder.render();

      效果:

     

     

     

     

     

    版权

    作者:Artwl

    出处:http://artwl.cnblogs.com

    本文首发博客园,版权归作者跟博客园共有。转载必须保留本段声明,并在页面显著位置给出本文链接,否则保留追究法律责任的权利。

  • 相关阅读:
    java,php,js;AES 互通加解密
    将本地代码上传github
    为什么我们做分布式使用Redis?
    Git服务器环境搭建(打造属于自己的存储库)
    Redhat6.5——解决yum功能不能正常使用
    数据库设计——评论回复功能
    nginx 配置信息
    Linux常用基础命令整理:关机命令、查看目录下文件命令等
    【Qt】QTabWidget 竖向 QTabBar横向
    Google BreakPad使用集
  • 原文地址:https://www.cnblogs.com/artwl/p/2867051.html
Copyright © 2011-2022 走看看