Холст HTML5: изменение цвета изображения

#javascript #css #html #canvas #html5-canvas

#javascript #css #HTML #холст #html5-холст

Вопрос:

У меня есть изображение (в оттенках серого), цвет которого я хочу изменить (в зависимости от пользователя). Поскольку довольно сложно изменить цвет изображения в оттенках серого, я предлагаю подход.

Изображение разделено на две части.

  1. Одним из них является изображение с белым цветом.
  2. Во-вторых, полупрозрачное изображение в оттенках серого.

Теперь я помещаю оба изображения друг на друга (с белым изображением внизу и изображением в оттенках серого сверху), чтобы при изменении цвета белого изображения оно было видно пользователю.

Проблема: этот подход работает для меня, за исключением одной проблемы. Когда я раскрашиваю белое изображение, оно будет пикселизироваться по углам.

JSFiddle: http://jsfiddle.net/pandey_mohit/BeSwL /

JSFiddle содержит три изображения для капсул:

  1. Верхняя часть капсулы Белое изображение (для раскрашивания)
  2. Нижняя часть капсулы Белое изображение (для раскрашивания)
  3. Полупрозрачное изображение для 3D-эффекта (с использованием оттенков серого)

Выберите красный, зеленый или синий цвет, чтобы увидеть проблему.

 function hexToRgb(color) {
    var shorthandRegex = /^#?([a-fd])([a-fd])([a-fd])$/i;
    color = color.replace(shorthandRegex, function(m, r, g, b) {
        return r   r   g   g   b   b;
    });

    var result = /^#?([a-fd]{2})([a-fd]{2})([a-fd]{2})$/i.exec(color);
    return result ? {
        r: parseInt(result[1], 16),
        g: parseInt(result[2], 16),
        b: parseInt(result[3], 16)
    } : {
        r: 0,
        g: 0,
        b: 0
    };
}

function colorImage(imgId,hexaColor) {
    // create hidden canvas (using image dimensions)
    var imgElement = document.getElementById(imgId);

    var canvas = document.createElement("canvas");
    canvas.width = imgElement.width;
    canvas.height = imgElement.height;

    var ctx = canvas.getContext("2d");
    ctx.drawImage(imgElement,0,0);

    var imageData = ctx.getImageData(0,0,canvas.width,canvas.height);

    var data = imageData.data;

    // convert image to grayscale
    var rgbColor = hexToRgb(hexaColor);

    for(var p = 0, len = data.length; p < len; p =4) {
        if(data[p 3] == 0)
           continue;
        data[p   0] = rgbColor.r;
        data[p   1] = rgbColor.g;
        data[p   2] = rgbColor.b;
        data[p   3] = 255;
    }
    ctx.putImageData(imageData, 0, 0);

    // replace image source with canvas data
    imgElement.src = canvas.toDataURL();
}

// changing color of capsule on select event
document.getElementById('sel_top').onchange = function(){
    colorImage('img_top', this.value);
}
document.getElementById('sel_bottom').onchange = function(){
    colorImage('img_bottom', this.value);
}
 

Ответ №1:

Ваш алгоритм перекраски устанавливает 4-й байт каждого квартета RGBA равным 255, что отбрасывает альфа-канал наложения и нарушает сглаживание по краям изображения. Сохранение альфа-канала оригинала дает лучшие результаты:

 for(var p = 0, len = data.length; p < len; p =4) {
    data[p   0] = rgbColor.r;
    data[p   1] = rgbColor.g;
    data[p   2] = rgbColor.b;
}
 

JSFiddle с закомментированными строками

Комментарии:

1. Можете ли вы использовать это для различных изображений?

2. @MisterJuanXDLOL Если у вас возникает конкретная проблема с применением этой техники к нескольким изображениям, не стесняйтесь задавать новый вопрос.