Kinetic JS — загрузка изображения в оттенках серого

Я пытаюсь использовать этот пример для загрузки изображения в градациях серого http://www.html5canvastutorials.com/advanced/html5-canvas-grayscale-image-colors-tutorial/. Поскольку на моей сцене много других объектов, я попытался использовать следующий скрипт:

var dImage1 = new Kinetic.Image({
                drawFunc: function (canvas) {
                    var context2 = canvas.getContext();
                    var x = 0;
                    var y = 0;
                    context2.drawImage(imageObj, x, y);
                    var imageData = context2.getImageData(x, y, imageObj.width, imageObj.height);
                    var data = imageData.data;

                    for (var i = 0; i < data.length; i += 4) {
                        var brightness = 0.34 * data[i] + 0.5 * data[i + 1] + 0.16 * data[i + 2];
                        data[i] = brightness;
                        data[i + 1] = brightness;
                        data[i + 2] = brightness;
                    }
                    context2.putImageData(imageData, x, y);
                }
            });
            layer1.add(dImage1);
            stage.add(layer1);

            var imageObj = new Image();
            imageObj.onload = function () {
                drawImage(this);
            };
            imageObj.src = .....;

Я получил эту ошибку: TypeMismatchError. Буду признателен за ваши предложения, заранее спасибо.


person hncl    schedule 12.04.2013    source источник


Ответы (1)


Я вижу пару ошибок в вашем коде...

Во-первых, несмотря на то, что в спецификации указано, что это необязательно, вам необходимо указать режим контекста ("2d").

// must specify "2d"

var context2 = canvas.getContext("2d"); 

Во-вторых, вам нужно полностью загрузить изображение, прежде чем использовать его в Kinetic.Image.

Итак, поместите создание Kinetic.Image в функцию и вызовите его в imageObj.onload:

function makeKineticImage(){

    var dImage1 = new Kinetic.Image({
        drawFunc: function (canvas) {
            var context2 = canvas.getContext("2d");
            var x = 0;
            var y = 0;
            context2.drawImage(imageObj, x, y);
            var imageData = context2.getImageData(x, y, imageObj.width, imageObj.height);
            var data = imageData.data;

            for (var i = 0; i < data.length; i += 4) {
                var brightness = 0.34 * data[i] + 0.5 * data[i + 1] + 0.16 * data[i + 2];
                data[i] = brightness;
                data[i + 1] = brightness;
                data[i + 2] = brightness;
            }
            context2.putImageData(imageData, x, y);
        }
    });
    layer1.add(dImage1);
}

stage.add(layer1);

// you must create your Kinetic.Image AFTER your image is loaded

var imageObj = new Image();
imageObj.onload = function () {
    makeKineticImage();
};
imageObj.src = .....;
person markE    schedule 12.04.2013
comment
Марк, можно ли изменить ширину и высоту изображения в этой строке: context2.getImageData(x, y, dicom1.width, dicom1.height); быть context2.getImageData(x, y, 512, 512); Я пытался, но не работал. Также как я могу добавить значение смещения? большое вам спасибо за вашу помощь. - person hncl; 12.04.2013
comment
Конечно. getImageData просто получает прямоугольный кусок пикселей, начиная с любого X/Y. Таким образом, вы можете получить квадратный фрагмент пикселей размером 512x512 с любым смещением X/Y, которое вы хотите, с помощью getImageData(myOffsetX,myOffsetY,512,512). Если вы получаете сообщение об ошибке, убедитесь, что вы не запрашивали пиксели за краями вашего холста... Итак, если ваш холст имеет размер 1000x1000 и вы делаете getImageData(700,700,512,512), вы получите сообщение об ошибке. - person markE; 12.04.2013
comment
Спасибо, Марк, смещение сработало, а размер изображения — нет; мне нужно изменить также putImageData? - person hncl; 12.04.2013
comment
Я изменил context2.drawImage(dicom1, x, y, ширина, высота); и это сработало, спасибо миллион. - person hncl; 12.04.2013
comment
Просто для ясности: вам не нужно передавать параметр 2d в getContext(). Параметр холста, переданный в функцию drawFunc, не является элементом холста, это специальный рендерер KineticJS. метод getContext() возвращает контекст элемента холста - person Eric Rowell; 13.04.2013
comment
мой плохой ... Хотя я действительно знал это о KineticJS, мой разум неправильно вспыхнул на обычный html-холст, где это требуется. Спасибо за резервную копию моего глюка! :) - person markE; 13.04.2013