#javascript #html5 #canvas #blur
Можно ли создать на canvas библиотеке Konva.js (или на каком-то другом) blur эффект на фото при mousemove? Читал документацию к Konva js, но ничего подходящего не нашел. Искал примеры, достойных примеров не нашел. Вот пример с встроенным фильтром в canvas ctx.filter = 'blur(5px)';.
Ответы
Ответ 1
Конечно можно было бы взять библиотеку, но и вручную можно добится неплохих результатов, а заодно и познакомится поближе с обработкой изображений. Это решение использунт прямые манипуляции с пикселями. Применяем ко всем пикселям области, которую необходимо заблюрить, так называемое "ядро свертки" (convolution kernel) - основа основ в обработке изображений. Вот тут подробно про это написано а так же визуализировано Запустите сниппет заново, если картинка не показательная (они псевдослучайные), в сниппете реализовано рисование блюром, как Вы просили в комментариях... let s = 44; // size of area to be blurred let kernel =[[0,0,1,0,0], [0,1,2,1,0], [1,2,3,2,1], [0,1,2,1,0], [0,0,1,0,0]]; let ctx = canvas.getContext('2d'); let total = kernel.flatMap(i => i).reduce((a, i) => a + Math.abs(i)), ks = (kernel.length-1)/2, // half of kernel size - 1 (pixels around center) s2 = s/2, // half size of area to be blurred sks2 = s+ks*2; // size of area of pixels needed to be processed img.onload = e => ctx.drawImage(img, 0, 0); addEventListener('mousedown', e => draw = true) addEventListener('mouseup', e => draw = false) addEventListener('mousemove', e => { if (!window.draw) return; var input = ctx.getImageData(e.layerX-s2-ks, e.layerY-s2-ks, sks2, sks2); var output = ctx.createImageData(s, s); for (var x = 0; x < s; x++) for (var y = 0; y < s; y++) handlePixel(input, output, x, y) ctx.putImageData(output, e.layerX - s2, e.layerY - s2) }) function handlePixel(i, o, x, y) { let offset = (y * s + x) * 4; // offset in output data (4=rgba) for (var kx = -ks; kx <= ks; kx++) for (var ky = -ks; ky <= ks; ky++) { let off = ((y+ks) * sks2 + (x+ks) + kx + ky * sks2) * 4; //offset in input for (var n = 0; n < 3; n++) o.data[offset + n] += kernel[kx+ks][ky+ks] * i.data[off+n] / total; } o.data[offset + 3] = 255; // always opaque } PS: от бага по краям надо подумать как избавиться...
Комментариев нет:
Отправить комментарий