Прозрачность потеряла с помощью метода getImageData - поддержка HTML5 2D-контекст
я заметил странную проблему с getImageData
; прозрачность изображения, кажется, игнорируется при извлечении данных изображения.
так как любое изображение должно быть нарисовано на canvas
прежде чем его данные изображения могут быть получены, я предположил, что это было проблемой с canvas
в вопросе тупить. Но я ошибался, так как использовал canvas
в качестве аргумента в drawImage
поддерживает прозрачность.
вот как я загрузил изображения;
var load_image = function(name, url, holder, callback) {
var img = new Image();
img.src = url;
img.addEventListener('load', function(e) {
var canvas = make_canvas(e.target.width, e.target.height);
var ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(e.target, 0, 0);
holder[name] = {canvas: canvas, ctx: ctx};
delete e.target;
callback.call();
}, false);
};
в callback
- это просто функция draw, которая вызывает draw_image
чтобы нарисовать изображение.
обычный версия;
var draw_image = function(ctx, img, sx, sy, w, h, dx, dy) {
ctx.drawImage(img.canvas, sx, sy, w, h, dx, dy, w, h);
};
он просто берет холст в качестве аргумента drawImage
, и результат, как и предполагалось, с сохранением прозрачности. пример.
версия данных изображения;
var draw_image = function(ctx, img, sx, sy, w, h, dx, dy) {
var imagedata = img.ctx.getImageData(sx, sy, w, h);
ctx.putImageData(imagedata, dx, dy);
};
этот получает данные изображения требуемого прямоугольника с того же холста, что и в обычной версии, и помещает данные изображения на холст, который я хочу нарисовать. Я считаю, что транспарентность должна поддерживаться, но это не так. пример. (Это ссылка Dropbox из-за origin-clean
флаг.)
я ошибаюсь, предполагая, что прозрачность должна поддерживаться с getImageData
? Или я просто неправильно его использую?
в любом случае, помощь будет действительно оценили.
1 ответов
Я считаю, что ваша проблема в том, что putImageData не использует составная операция для смешивания данных изображения источника и назначения. Скорее, он делает прямую запись красного, зеленого, синего,Альфа каналы на холст. Для полностью прозрачных пикселей это означает, что они могут отображаться или не отображаться в ожидаемом цвете.
вместо этого вы можете создать промежуточный элемент canvas, нарисовать его, а затем использовать drawImage() для рендеринга целевой холст с соответствующим globalCompositeOperation применяется. маска для putImageData с холстом HTML5? обсуждает этот вопрос более подробно.
Update: вы можете проверить, что данные, которые вы записываете в свой "сломанный" пример, на самом деле имеют прозрачные данные, выполнив ctx.getImageData(230,50,1,1).data
. Результат [0,0,0,0] - т. е. полностью прозрачный пиксель.