Разделение изображения на каналы RGBA
Первое, что вы не можете отделить каналы от изображения. Вы можете установить только нежелательные каналы на ноль. Однако установка нулевого альфа-канала автоматически обнулит все каналы. Таким образом, вы должны сохранить альфа-канал.
Копировать изображение
Чтобы скопировать изображение, создайте второй холст и нарисуйте на нем оригинальное изображение.
Следующая функция сделает это
function copyToCanvas(image) {
const can = document.createElement("canvas");
can.width = image.naturalWidth || image.width;
can.height = image.naturalHeight || image.height;
can.ctx = can.getContext("2d");
can.ctx.drawImage(image, 0, 0);
return can;
}
Удаление данных канала
Для удаления двух ненужных данных канала из изображения, скопированного предыдущим способом, требуется два шага.
- Использование составной операции
"multiply"
для удаления нежелательных данных канала. - Приведенный выше шаг устанавливает альфа-канал на 255. Чтобы вернуть альфа-канал, вы используете составную операцию
"destination-in"
и рисуете оригинальное изображение поверх нового изображения.
Следующая функция скопирует изображение, удалит ненужные данные канала и сохранит альфа-канал без изменений.
const channels = {
red: "#F00",
green: "#0F0",
blue: "#00F",
};
function getChannel(channelName, image) {
const copy = copToCanvas(image);
const ctx = copy.ctx;
ctx.fillStyle = channels[channelName];
ctx.globalComposietOperation = "multiply";
ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.globalComposietOperation = "destination-in";
ctx.drawImage(image, 0, 0);
ctx.globalComposietOperation = "source-over";
return copy;
}
Получение каналов RGB
Поскольку альфа-канал поддерживается, вам нужно только отделить красный зеленый и синий каналы.
Используя предыдущую функцию, следующее создаст объект содержит оригинальное изображение и 3 канала
function seperateRGB(image) {
return {
red: getChannel("red", image),
green: getChannel("green", image),
blue: getChannel("blue", image),
};
}
рекомбинирование каналов
Теперь, когда каналы разделены, вы можете рекомбинировать каналы, сначала создав новый холст того же размера, что и исходный image плюс любые смещения, которые вы добавляете при рекомбинации изображения (если вы не добавляете обратно альфа).
function createCanvas(w, h) {
const can = document.createElement("canvas");
can.width = w;
can.height = h;
can.ctx = can.getContext("2d");
return can;
}
Затем нарисуйте первый канал (может быть любым из 3) на новом холсте. Затем нарисуйте два других канала, используя составную операцию "lighter"
. Затем восстановите альфа, используя составную операцию "destination-in"
const RGB = seperateRGB(image);
const recombined = createCanvas(RGB.red.width, RGB.red.height);
const ctx = recombined.ctx;
ctx.drawImage(RGB.red, -2, -2);
ctx.globalCompositeOperation = "lighter";
ctx.drawImage(RGB.green, 0, 0);
ctx.drawImage(RGB.blue, 2, 2);
ctx.globalCompositeOperation = "destination-in";
ctx.drawImage(image, 0, 0);
ctx.globalCompositeOperation = "source-over";
Все сделано
Элемент canvas recombined
содержит рекомбинированное изображение со смещением зеленого и синего каналов на 2 пикселя и исходной альфа восстановлено.
Обратите внимание, что вам не нужно восстанавливать альфа. Восстановление альфы, если некоторые каналы смещены, удалит некоторые неперекрывающиеся пиксели.