javascript 画布 - IndexSizeError:索引或大小为负或大于允许的数量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19338032/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 15:14:11  来源:igfitidea点击:

Canvas - IndexSizeError: Index or size is negative or greater than the allowed amount

javascriptcanvas

提问by brandongray

So in Firefox I'm getting this error in the console when using drawImage on a canvas element.

因此,在 Firefox 中,当在画布元素上使用 drawImage 时,我在控制台中收到此错误。

"IndexSizeError: Index or size is negative or greater than the allowed amount"

Everything is working fine in Chrome. Common causes for this I found were returning negative values or trying to draw the image to the canvas before the image is actually loaded. Neither of which seem to be the case. What am I missing here?

在 Chrome 中一切正常。我发现这种情况的常见原因是返回负值或尝试在实际加载图像之前将图像绘制到画布上。这两种情况似乎都不是。我在这里错过了什么?

Any ideas would be greatly appreciated. http://jsfiddle.net/Ra9KQ/3/

任何想法将不胜感激。http://jsfiddle.net/Ra9KQ/3/

var NameSpace = NameSpace || {};

NameSpace.Pixelator = (function() {

    var _cache = {
        'wrapper' : null,
        'canvas'  : null,
        'ctx'     : null,
        'img'     : new Image()
    },

    _config = {
        'canvasWidth'      : 250,
        'canvasHeight'     : 250,
        'isPlaying'        : false,
        'distortMin'       : 3,
        'distortMax'       : 100,
        'distortValue'     : 100, // matches distortMax by default
        'initDistortValue' : 3,
        'speed'            : 2.5,
        'delta'            : 2.5,   // delta (+/- step), matches speed by default
        'animation'        : null,
        'origImgWidth'     : null,
        'origImgHeight'    : null,
        'imgHeightRatio'   : null,
        'imgWidthRatio'    : null,
        'newImgWidth'      : null,
        'newImgHeight'     : null
    },

    _init = function _init() {

        _setupCache();
        _setupCanvas();
        _setupImage();

    },

    _setupCache = function _setupCache() {

        _cache.wrapper = $('#dummy-wrapper');
        _cache.canvas = document.getElementById('dummy-canvas');
        _cache.ctx = _cache.canvas.getContext('2d');

    },

    _setupCanvas = function _setupCanvas() {

        _cache.ctx.mozImageSmoothingEnabled = false;
        _cache.ctx.webkitImageSmoothingEnabled = false;
        _cache.ctx.imageSmoothingEnabled = false;

    },

    _setupImage = function _setupImage() {

        _cache.img.onload = function() {

            _adjustImageScale();
            _pixelate();
            _assignEvents();

        };

        _cache.img.src = _cache.canvas.getAttribute('data-src');

    },

    _adjustImageScale = function _adjustImageScale() {

        var scaledHeight,
            scaledWidth;

        _config.origImgWidth = _cache.img.width;
        _config.origImgHeight = _cache.img.height;
        _config.imgHeightRatio = _config.origImgHeight / _config.origImgWidth;
        _config.imgWidthRatio = _config.origImgWidth / _config.origImgHeight;

        scaledHeight = Math.round(250 * _config.imgHeightRatio);
        scaledWidth = Math.round(250 * _config.imgWidthRatio);

        if (scaledHeight < 250) {

            _config.newImgHeight = 250;
            _config.newImgWidth = Math.round(_config.newImgHeight * _config.imgWidthRatio);

        } else if (scaledWidth < 250) {

            _config.newImgWidth = 250;
            _config.newImgHeight = Math.round(_config.newImgWidth * _config.imgHeightRatio);

        }

    },

    _assignEvents = function _assignEvents() {

        _cache.wrapper.on('mouseenter', _mouseEnterHandler);
        _cache.wrapper.on('mouseleave', _mouseLeaveHandler);

    },

    _mouseEnterHandler = function _mouseEnterHandler(e) {

        _config.delta = -_config.speed;

        if (_config.isPlaying === false) {
            _config.isPlaying = true;
            _animate();
        }

    },

    _mouseLeaveHandler = function _mouseLeaveHandler(e) {

        _config.delta = _config.speed;

        if (_config.isPlaying === false) {
            _config.isPlaying = true;
            _animate();
        }

    },

    _pixelate = function _pixelate(val) {

        var size = val ? val * 0.01 : 1,
            w = Math.ceil(_config.newImgWidth * size),
            h = Math.ceil(_config.newImgHeight * size);

        console.log('w: ' + w,'h: ' + h,'_config.newImgWidth: ' + _config.newImgWidth,'_config.newImgHeight: ' + _config.newImgHeight);

        _cache.ctx.drawImage(_cache.img, 0, 0, w, h);

        _cache.ctx.drawImage(_cache.canvas, 0, 0, w, h, 0, 0, _config.canvasWidth, _config.canvasHeight);

    },

    _animate = function _animate() {

        // increase/decrese with delta set by mouse over/out
        _config.distortValue += _config.delta;

        if (_config.distortValue >= _config.distortMax || _config.distortValue <= _config.distortMin) {

            _config.isPlaying = false;
            cancelAnimationFrame(_config.animation);
            return;

        } else {

            // pixelate
            _pixelate(_config.distortValue);
            _config.animation = requestAnimationFrame(_animate);

        }

    };

    return {
        init: _init
    };

})();

NameSpace.Pixelator.init();

采纳答案by brandongray

When you are using clipping you need to make sure that the source region is within the image (not necessary for target as this will be clipped by canvas).

当您使用剪辑时,您需要确保源区域在图像内(目标不需要,因为这将被画布剪辑)。

So if you add restriction control it should work. Here is one way of doing this (before using the clipping functionality of drawImage):

因此,如果您添加限制控制,它应该可以工作。这是执行此操作的一种方法(在使用 的剪辑功能之前drawImage):

if (w > _config.canvasWidth) w = _config.canvasWidth;
if (h > _config.canvasHeight) h = _config.canvasHeight;

_cache.ctx.drawImage(_cache.canvas, 0, 0, w, h,
                      0, 0, _config.canvasWidth, _config.canvasHeight);

Modified fiddle here.

修改小提琴here

Tip 1:
Normally this also applies to x and y but as these are 0 here there is no need to check.

提示 1:
通常这也适用于 x 和 y,但由于此处为 0,因此无需检查。

Tip 2:
If you need the image to be drawn narrower than you need to instead of changing source region, change the target region.

提示 2:
如果您需要将图像绘制得比您需要的更窄,而不是更改源区域,请更改目标区域。

回答by moka

Widthand Heightof image you draw when you specify size values should be larger or equal to 1. As well for performance advantages floorall values you pass to it.
If width and/or height is 0, it will result in:

指定大小值时绘制的图像的宽度高度应大于或等于 1。对于性能优势,floor您传递给它的所有值也是如此。
如果宽度和/或高度为 0,它将导致:

IndexSizeError: Index or size is negative or greater than the allowed amount

In Firefox:

在 Firefox 中:

width = Math.max(1, Math.floor(width));
height = Math.max(1, Math.floor(height));
ctx.drawImage(image, x, y, width, height);

回答by Draeli

To help others, I had the same problem in canvas and I solve taking account on image load, for example :

为了帮助其他人,我在画布上遇到了同样的问题,我解决了考虑图像加载的问题,例如:

var image = new Image();
image.crossOrigin = "use-credentials";
image.onload = function(){
    // here canvas behavior
};
image.src = imgSrc;

回答by Mahdi

I had the same problem but in IEand Safari. There were three things in particular that I had to fix:

我有同样的问题,但在IESafari 中。我特别需要解决三件事:

1) I had to set the widthand heightof the image manually.

1)我必须手动设置图像的widthheight

var image = new Image();
...
image.width = 34;
image.height = 34;

2) I had to avoid using negative offset when creating ol.style.Icon. In this case I had to change my SVG icon, but that pretty much depends to your icon. So this would cause exception because of the negative offset:

2)我在创建ol.style.Icon. 在这种情况下,我不得不更改我的 SVG 图标,但这在很大程度上取决于您的图标。所以这会因为负偏移量而导致异常:

var icon = new ol.style.Style({
    "image": new ol.style.Icon({
        ...
        "offset": [0, -50]
    })
});

3) I had to roundthe width and height values. As some of them were calculated dynamically, I had values like 34.378which were causing problems. So I had to round them and pass the Integervalue.

3)我不得不入宽度和高度值。由于其中一些是动态计算的,因此我有34.378一些会导致问题的值。所以我不得不对它们进行四舍五入并传递数值。