[Авторский взгляд на предпринимательство и бизнес XXI века]

Как изменить цвет в картинке с помощью JavaScript?

22 ноября 2014 года
2014-11-22https://shishmakov.com
Изменение цвета на JavaScript

Совсем недавно при разработке одного из проектов столкнулся с необходимостью на стороне клиента перекрасить изображение. А именно: заменить один цвет на другой.

(!) В русскоязычном интернете решение найдено не было, поэтому ниже привожу подсказку зарубежных коллег.

Может возникнуть вопрос: почему нельзя просто загрузить отдельное изображение с другим цветом?

Ответ прост: нагрузка на сервер должна быть максимально низкой. Вы можете возвращать клиенту два вида изображений (с оригинальным цветом и замененным), но это требует больше трафика и запросов к серверу (два против одного).

Более рациональным может быть трата сравнительно небольших ресурсов на стороне пользователя (который этого даже не заметит) на замену цвета, но в итоге производительность сервера повысится.

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

Реализация основывается на canvas. Да, это означает, что пользователи IE8 и более ранних не увидят изменений. Но, согласитесь: вы используете border-radius и другие CSS3-свойства из-за удобства, «забивая» на поддержку старых монстров. И это никому не мешает.

Если ещё кто-то по доброй воле использует Windows XP, то вряд ли он пользуется вместе с ним IE8. Это самоубийство. Однако это тема другой статьи.

Итак, метод основывается на canvas. Вот его алгоритм:

  1. Взять необходимо изображение
  2. Поместить его на холст canvas
  3. Сравнить цвет каждого пикселя холста с тем, о которого необходимо избавиться
  4. Заменить совпавшие цвета на необходимые
  5. Вернуть готовое изображение

Для удобства мы принимаем и возвращаем изображение в base64. Но этот участок функции можно легко модифицировать.

Функция:

function changeColorURI(data, oldColor, newColor)
{
    var img, cnv, cnt, imgData;
    img = document.createElement('img');
    img.src = data;
    cnv = document.createElement('canvas');
    cnv.width = img.width;
    cnv.height = img.height;
    ctx = cnv.getContext('2d');
    ctx.drawImage(img, 0, 0);
    imgData = ctx.getImageData(0, 0, cnv.width, cnv.height)
    data = imgData.data;
    for(var x = 0, len = data.length; x < len; x += 4)
    {
        if((data[x] == oldColor[0]) && (data[x + 1] == oldColor[1]) && (data[x + 2] == oldColor[2]))
        {
            data[x] = newColor[0];
            data[x + 1] = newColor[1];
            data[x + 2] = newColor[2];
        }
    }
    ctx.putImageData(imgData, 0, 0);
    return cnv.toDataURL();
}

На вход поступает закодированное изображение (переменная data), заменяемый цвет в виде массива, состоящего из 3х цветов модели RGB (переменная oldColor), заменяющий цвет также в виде массива (переменная newColor).

Функцию можно доработать, передавая цвета в HEX-формате и переводить в RGB средствами JavaScript.

 
Важно!

Не стоит пользоваться функцией, если необходимо заменять одновременно 3 и более изображений в особенности, если они больших размеров. В таких случая задержка будет весьма заметной для пользователя, а в худшем случае можно и вовсе «повесить» браузер.

Функцию хорошо применять, если у вас есть спрайт с несколькими иконками одного цвета, которые необходимо одновременно перекрасить.

Дмитрий Шишмаков
Теги: ,
Дмитрий Шишмаков Dmitry Shishmakov

Об авторе:

Привет! Меня зовут Дмитрий Шишмаков, и я автор этого блога. Чуть больше информации обо мне можно найти здесь.

Всех, кто читает мои статьи, я буду искренне рад видеть среди своих друзей на Facebook и в ВКонтакте. Присоединяйтесь!

Обнаружили ошибку в тексте? Выделите её и нажмите [Ctrl]+[Enter]
Оцените статью:
Пока нет оценок
Понравилась статья? Поделитесь своими впечатлениями в комментариях ↓