Canvas расщепляет изображение на компоненты rgba - PullRequest
0 голосов
/ 30 марта 2020

Я пытаюсь разделить черно-белое изображение на его компоненты RGB и сместить каждый слой, установив его наложение. Идея состоит в том, чтобы немного вычеркнуть изображение героя и слегка переместить его в случайном порядке.

Мне интересно, действительно ли это правильный подход к этому.

Я стремлюсь к sh браузер, если я осмелюсь добавить консольный журнал в функцию, чтобы увидеть, где я иду не так.

Кто-нибудь делал такие манипуляции в браузере, и это жизнеспособно?

https://github.com/Julieslv/image-shift/blob/master/index.js

1 Ответ

0 голосов
/ 31 марта 2020

Разделение изображения на каналы 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;
}

Удаление данных канала

Для удаления двух ненужных данных канала из изображения, скопированного предыдущим способом, требуется два шага.

  1. Использование составной операции "multiply" для удаления нежелательных данных канала.
  2. Приведенный выше шаг устанавливает альфа-канал на 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 пикселя и исходной альфа восстановлено.

Обратите внимание, что вам не нужно восстанавливать альфа. Восстановление альфы, если некоторые каналы смещены, удалит некоторые неперекрывающиеся пиксели.

...