HTML5 - неожиданные результаты с холстом drawImage - PullRequest
1 голос
/ 22 сентября 2011

Я только учусь использовать элемент HTML5 canvas.Я успешно рисовал прямоугольники, вызывал getImageData, манипулировал пикселями, а затем putImageData, чтобы увидеть, как прямоугольники меняют цвет, и т. Д.

Теперь я пытаюсь загрузить изображение в холст I 'мы наткнулись на препятствие.После вызова drawImage для контекста холста, fillRect рисует только в областях, в которые не было нарисовано изображение, например, рисует прямоугольники за изображениями, даже если он вызывается после drawImage.Кроме того, putImageData перестает работать, даже на видимых областях, содержащих прямоугольники, мои манипуляции с пикселями больше не происходят.Если я закомментирую строку с drawImage, она снова заработает.

То, что я хочу сделать, это манипулировать пикселями на изображении так же, как я делал с прямоугольниками.Есть ли какая-либо причина, по которой это не сработает?

Нарисуйте код изображения:

var img = new Image();
img.onload = function () {
     //comment out the following line, everything works, but no image on canvas
     //if it's left in, the image sits over the rectangles, and the pixel
     //manipulation does not occur
     context.drawImage(img, 0, 0, width / 2, height / 2);
}
img.src = path;

Нарисуйте код прямоугольников:

for (var i = 0; i < amount; i++)
{
    x = random(width - size);
    y = random(height - size);
    context.fillStyle = randomColor();
    context.fillRect(x, y, size, size);
}

Код пикселей с манипулированием:

var imgd = context.getImageData(0, 0, width, height);
var pix = imgd.data;

//loop through and do stuff

context.putImageData(imgd, 0, 0);

Ответы [ 2 ]

2 голосов
/ 22 сентября 2011

Ничто не выглядит особенно неправильно с кодом, который вы разместили. Дайте нам весь код или рассмотрите следующее:

  1. Вы меняете globalCompositeOperation в любом месте?
  2. randomColor() делает цвета слишком прозрачными, чтобы их видеть?
  3. Есть ли регион отсечения, о котором вы не упомянули?
  4. Вы рисуете все в правильном контексте?
  5. Есть ли орфографическая ошибка, которая останавливает выполнение и вызывает ошибку?
  6. Возможно, ваша последовательность событий неверна. Вы можете загрузить изображение, затем нарисовать прямоугольники, а затем закончить загрузку изображения, чтобы оно выглядело так, как будто прямоугольники были нарисованы позади вашего изображения, когда это было просто в естественном порядке.
  7. Вызывает ли putImageData ошибку безопасности (ее легче увидеть в Firefox), поскольку изображение было нарисовано на холсте из другого домена? Эта ошибка может остановить все последующее выполнение кода рисования и, следовательно, дать эффект, который вы описываете. Посмотрите, нарушаете ли вы одно из этих правил. В частности, рисование изображения на холсте из другого источника и затем попытка использовать getImageData.

Скорее всего, это последний или второй-последний элемент в моем списке, который вызывает у вас горе.

Попробуйте разместить изображение на своем собственном сервере и посмотрите, исчезнет ли оно, или посмотрите на веб-консоль в Firefox, чтобы узнать, жалуется ли оно на ошибку безопасности.

Или просто откройте веб-консоль в Chrome / IE9 и посмотрите, действительно ли код рисования ударил при рисовании изображения

0 голосов
/ 23 сентября 2011

ОК, Саймон поставил меня на правильный путь.Похоже, что браузеры обрабатывают файлы из локальной файловой системы иначе, чем файлы с веб-сервера - в частности, файлы изображений помечаются как origin-clean = false.Это вызывало исключение безопасности (NS_ERROR_DOM_SECURITY_ERR 1000), когда я пытался вызвать getImageData в контексте после отрисовки изображения.

Решение 1 - разместить файлы на веб-сервере.

Решение 2 немного взломано, но оно подходит для моих целей:

try {
    try { 
        var imgd = context.getImageData(0, 0, width, height); 
    } catch (e) { 
    netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
        var imgd = context.getImageData(0, 0, width, height);
    }
} catch (e) {throw new Error("unable to access image data: " + e)}

Если выдается исключение безопасности, браузер предложит пользователю разрешить переопределение.

...