2013-10-09 5 views
0

Я работаю над некоторыми анимациями частиц для своего игрового движка, и я хочу знать, можно ли изменить hue, гамму и другие свойства изображения объекта ImageElement объекта холст, сохраняя форму изображения.Изменение оттенка/оттенка элемента изображения на холсте

То, что я пытался до сих пор это:

_ctx.save(); 
_ctx.setStrokeColorHsl(240, 100, 50); 
_ctx.fillRect(c.x, c.y, width, height); 
_ctx.globalAlpha = nAlpha; //Modify the transparency 
_ctx.drawImageScaled(p, c.x, c.y, width, height); 
_ctx.restore(); 

который работает, но он применяет тон всей части изображения, что означает, если изображение является PNG с прозрачными краями он будет рисуйте даже прозрачные части, потому что он использует «fillRect()» (который рисует только прямоугольники), чтобы применить преобразование и объект изображения.

Результат заключается в следующем: (красные частицы представляют собой полупрозрачные круги)

Attempt of a bonfire

Есть ли другой способ подкрашивать форму съемки изображения или только модифицировать объект непосредственно таким преобразованием только применимы к видимой части изображения?

ответ

1

Вы должны использовать режимы globalCompositeOperation. Нарисуйте свое изображение сначала, может быть, затем fillRect с globalAlpha и globalCompositeOperation = 'source-atop'.

https://developer.mozilla.org/samples/canvas-tutorial/6_1_canvas_composite.html

так что вы можете играть вокруг этих режимов, используя зажигалку, чтобы облегчить и раскрасить изображение, или назначения-кадр для добавления фона.
Но будьте осторожны, некоторые режимы не работают на всех браузерах, я проверил darker несколько месяц назад, которые к тому времени не работали.

+0

Удивительно! он работал, но мне не нужно было использовать метод fillRect, нужно было использовать только глобальный составной компонент (http://api.dartlang.org/docs/releases/latest/dart_html/CanvasRenderingContext2D.html#globalCompositeOperation) и fillStyle и сделал это: _ctx.globalCompositeOperation = 'lighter'; _ctx.fillStyle = "# f30"; –

1

Я не знаю о встроенном способе сделать это. Один из способов, которым вы могли бы это сделать, - это рисовать изображение на временном холсте и сами изменять пиксели изображения. Но вам понадобятся функции для преобразования между RGB и HSL. Вы можете использовать этот метод, чтобы сделать то же самое с насыщенностью и легкостью.

double hue = 0.8; 

var data = _context.getImageData(0, 0, _canvas.width, _canvas.height); 
var pixels = data.data; 
List<double> hsl; 
List<int> newPixel; 

for(var i = 0, len = pixels.length; i < len; i += 4) { 
    hsl = rgbToHsl(pixels[i + 0], pixels[i + 1], pixels[i + 2]); 

    newPixel = hslToRgb(h, hsl[1], hsl[2]); 
    // or newPixel = hslToRgb((hsl[0] + hue) % 1.0, hsl[1], hsl[2]); 

    pixels[i + 0] = newPixel[0]; 
    pixels[i + 1] = newPixel[1]; 
    pixels[i + 2] = newPixel[2]; 
} 
_context.putImageData(data, 0, 0); 

Другим способом, с помощью метода вам, может быть дополнительно использовать базовое изображение в качестве маски для холста с измененным оттенком. Вам нужно будет прокрутить пиксели и изменить pixel[i + 3] на альфа базового изображения. Но вам не придется конвертировать между HSL и RGB.

+0

2 вещи, один из которых вы по-прежнему включаете: var data = _context.getImageData (0, 0, _canvas.width, _canvas.height); В основном это прямоугольник, то же самое, и во-вторых, поскольку я опасался, что этот вид манипуляции пикселями по пикселям действительно неэффективен и вызывает плохой кадр в секунду, я собираюсь попробовать, возможно, подход css к этому, поскольку обработка данные изображения не выглядят как хороший вариант. –

Смежные вопросы