博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Javascript图像处理之虚拟边缘
阅读量:6969 次
发布时间:2019-06-27

本文共 8877 字,大约阅读时间需要 29 分钟。

  原理来自的一文。  

/* * 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();

  效果:

 

 

 

 

 

转载地址:http://prasl.baihongyu.com/

你可能感兴趣的文章
HDFS dfsclient读文件过程 源码分析
查看>>
C#写爬虫,版本V2.0
查看>>
03 弹性盒模型
查看>>
iOS_Swift初识之使用三种回调方式自定义Button
查看>>
socket(孔、插座 --> 套接字) Socket通信 -- 了解
查看>>
第二章 数据的存储和读入
查看>>
a前缀
查看>>
LeetCode第七天
查看>>
java中json的使用和解析
查看>>
C语言面试笔试整理笔记(二)
查看>>
Hibernate 5.x 配置 C3P0 数据库连接池
查看>>
自测是保证开发提交代码质量的最基本方法和最低要求
查看>>
Java_myeclipse添加DTD约束(框架xml只能提示功能)
查看>>
CSS3基础知识学习
查看>>
eclipse 创建普通maven项目
查看>>
vue webpack build 打包过滤console.log()日志
查看>>
iOS — Autolayout之Masonry解读
查看>>
ORACLE存储过程 练习系列三 失效或者生效指定表的外键
查看>>
用户表空间查询
查看>>
求整数数组中最大子数组的和
查看>>