Как сделать Instagram в браузере — Дмитрий Дудин, xbSoftware

Post on 11-Nov-2014

564 views 1 download

Tags:

description

Дмитрий расскажет о: применении фильтров и эффектов для изображений прямо в браузере; достоинствах и недостатках Canvas, WebGl, SVG и CSS-фильтров и шейдеров; неизведанном мире SVG-фильтров, его продуманных до мелочей устоях, синтаксисе и правилах; возможностях обработки изображений — от простых чёрно-белых картинок до нелинейных искажений и градиентных карт. В докладе будет минимум скучной теории и максимум живых примеров.

Transcript of Как сделать Instagram в браузере — Дмитрий Дудин, xbSoftware

Как сделатьInstagram в браузереДмитрий Дудин @nedudi

Приукрасить

Придать настроение

Нелиней

ные искажен

ия

Устоявшиеся практики

•  Десктопный софт:

•  Photoshop

•  Photobooth Mac OS X, XnRetro ...

•  Мобильные приложения:

•  Instagram

•  Snapseed, Camera+ и еще 100500 разных...

6

Фильтрация изображений в веб несколько лет назад:

1.  Flash

2.  Отправляем на сервер,

там фильтруем,

возвращаем обратно на клиент

и все это время ждем, ждем, ждем...

7

Все меняется к лучшему

Способы фильтрации на клиентесегодня и в ближайшем будущем:

1.  Canvas

2.  WebGL

3.  CSS-фильтры

4.  CSS-шейдеры

5.  SVG-фильтры

6.  SVG-фильтры для HTML

9

Canvas

var canvas = document.createElement('canvas');

var context = canvas.getContext('2d');

context.drawImage(img);

var imgd = context.getImageData(0, 0, w, h)

var pixels = imgd.data;

11

Не нужно изобретать свой велосипед

12

13

vintageJS

$(img).vintage({

  contrast:32,

  lighten:0.4,

  noise: 20,

  desaturate: 0.05

});

14

15

camanJS

Caman("image.jpg", "#canvas", function () {

  this

    .saturation(20)

    .gamma(1.4)

    .vignette(300, 60)

    .render();

});

16

Достоинства фильтрации с Canvas

1.  IE 9 + и мобильные браузеры.

2.  Много готовых решений, библиотек, плагинов.

3.  Фильтры могут быть настолько сложными и

нестандартными, насколько у вас хватит

фантазии

. . . и насколько вы разбираетесь в цифровой

обработке изображений :)

17

Недостатки фильтрации с Canvas

1.  Нельзя отфильтровать картинки с других

доменов (включая поддомены) из-за

ограничений безопасности. Решается

проксированием или переводом в base64.

2.  Сложные фильтры это медленная,

блокирующая операция.

Десктопный браузер подтормаживает…

Мобильный браузер серьезно тупит.18

WebGL

Что это о_O ?

precision mediump float;

varying vec2 position;

uniform sampler2D webcam;

void main() {

  vec2 p = position;

  vec4 color = texture2D(webcam, p);

  color.rgb = 1.0 ‐ color.rgb;

  gl_FragColor = color;

}

20

Шейдеры

•  Шейдер - кусок кода, который описывает

алгоритм обработки каждого пикселя в GPU.

•  Достоинство - возможность пользоваться

параллельной архитектурой GPU.

•  Бывают векторными и пиксельными (Fragment

Shaders)

•  Описываются в синтаксисе GLSL (OpenGL

Shading Language)21

Вернемся к cтрашному шейдеру

precision mediump float;

varying vec2 position;

uniform sampler2D webcam;

void main() {

  vec2 p = position;

  vec4 color = texture2D(webcam, p);

  color.rgb = 1.0 ‐ color.rgb;

  gl_FragColor = color;

}

22

Велосипеды в WebGl - это больно

23

Достоинства glfx

1.  Множество предустановленных фильтров.

2.  Красивый и понятный API.

3.  Возможность расширять библиотеку своими

шейдерами.

25

WebGLImageFilter

26

WebGLImageFilter прост виспользовании

var filter = new WebGLImageFilter();

filter.addFilter('hue', 180);

filter.addFilter('negative');

filter.addFilter('blur', 7);

var filteredImage = filter.apply(inputImage);

27

Достоинства фильтрации с WebGL

1.  Очень, очень, очень быстро.

2.  Есть несколько хороших плагинов.

3.  Можно использовать готовые шейдеры

написаные на языке GLSL

для OpenGL за последние 14 лет

(начиная c 2001 года)

28

Недостатки фильтрации с WebGL

1.  Слабая поддержка браузерами.

Chrome, Opera - отлично,

FF, Safari, IE11 - частично,

все остальные - никак.

2.  Для нестандартных операций порог входа

достаточно высок.

29

CSS-фильтры

Синтаксис CSS-фильтров

‐webkit‐filter:

  brightness(1.4)

  contrast(2)

  hue‐rotate(300deg)

  sepia(0.3);

31

Достоинства CSS-фильтров

1.  Быстрые.

2.  Очень удобно описываются.

34

Недостатки CSS-фильтров

1.  Пока только webkit(blink) браузеры.

2.  Ничего кроме типовых операций.

т.е. … Инстаграма с ними не сделаешь :(

35

CSS-шейдеры

Синтаксис

img {

    ‐webkit‐filter: custom(

      none

      mix(

        url(someFragmentShader.fs)

        normal

        source‐atop

      )

    );

}

37

someFragmentShader.fs

precision mediump float;

void main()

{

  css_ColorMatrix = mat4(1.0, 0.0, 0.0, 0.0,

                         0.0, 0.0, 0.0, 0.0,

                         0.0, 0.0, 0.0, 0.0,

                         0.0, 0.0, 0.0, 1.0);

}

38

Достоинства CSS-шейдеров

1.  Быстрые.

2.  Можно делать сложные нестандартные

эффекты.

40

Недостатки CSS-шейдеров

1.  Сложность описания, высокий порог входа.

2.  Вообще нигде толком не поддерживаются :)

41

SVG-фильтры

Нарисуем круг

<svg width="400" height="400">

    <circle

      cx="200"

      cy="200"

      fill="#3498db"

      r="100"/>

</svg>

43

Это круг :)

44

Простейший svg-фильтр (blur)

<svg width="400" height="400">

  <defs>

    <filter id="f0">

      <feGaussianBlur stdDeviation="50" />

    </filter>

  </defs>

  <circle filter="url(#f0)" cx="200" cy="200"

  fill="#3498db" r="100"/>

</svg>

45

Простейший svg-фильтр (blur)

<svg width="400" height="400">

  <defs>

    <filter id="f0">

      <feGaussianBlur stdDeviation="50" />

    </filter>

  </defs>

  <circle filter="url(#f0)" cx="200" cy="200"

  fill="#3498db" r="100"/>

</svg>

46

Простейший svg-фильтр (blur)

<svg width="400" height="400">

  <defs>

    <filter id="f0">

      <feGaussianBlur stdDeviation="50" />

    </filter>

  </defs>

  <circle filter="url(#f0)" cx="200" cy="200"

  fill="#3498db" r="100"/>

</svg>

47

Простейший svg-фильтр (blur)

<svg width="400" height="400">

  <defs>

    <filter id="f0" >

      <feGaussianBlur stdDeviation="40" />

    </filter>

  </defs>

  <circle filter="url(#f0)" cx="200" cy="200"

  fill="#3498db" r="100"/>

</svg>

48

Результат

49

Картинка внутри SVG

<svg width="1024" height="768">

  <image

    width="100%"

    height="100%"

    xlink:href="img/girl.jpg" />

</svg>

50

Картинка внутри SVG + blur

<svg width="1024" height="768">

  <defs>

    <filter id="f1" >

      <feGaussianBlur stdDeviation="10" />

    </filter>

  </defs>

  <image filter="url(#f1)" xlink:href="img/girl.jpg"

  width="100%" height="100%" />

</svg>

51

Комбинация фильтров

<filter id="f2">

  <feGaussianBlur stdDeviation="3" />

  <feColorMatrix type="saturate" values="0">

  </feColorMatrix>

</filter>

54

Комбинация фильтров

<filter id="f2">

  <feGaussianBlur result="a1" stdDeviation="3" />

  <feColorMatrix type="saturate" values="0">

  </feColorMatrix>

</filter>

55

Комбинация фильтров

<filter id="f2">

  <feGaussianBlur result="a1" stdDeviation="3" />

  <feColorMatrix in="a1" type="saturate" values="0">

  </feColorMatrix>

</filter>

56

Комбинация фильтров

<filter id="f2">

  <feGaussianBlur result="a1" stdDeviation="3" />

  <feColorMatrix in="a1" type="saturate" values="0">

  </feColorMatrix>

</filter>

57

Типы SVG-фильтров

<fe…Фильтр>

feComponentTransfer

feComponentTransfer

<feComponentTransfer>

  <feFuncR type="linear" slope="5" intercept="‐0.5"/>

  <feFuncG type="linear" slope="0.2"/>

  <feFuncB type="linear" slope="0.2"/>

  <feFuncA type="identity"/>

</feComponentTransfer>

61

feComponentTransfer

<feComponentTransfer>

  <feFuncA type="linear" slope="0.5"/>

</feComponentTransfer>

63

feComponentTransfer

<feComponentTransfer>

  <feFuncR type="linear" slope="0"/>

  <feFuncG type="linear" slope="0"/>

  <feFuncB type="linear" slope="1"/>

</feComponentTransfer>

65

feComponentTransfer

<feComponentTransfer>

  <feFuncR type="linear" slope="10" intercept="‐4"/>

  <feFuncG type="linear" slope="1.5" intercept="1"/>

  <feFuncB type="linear" slope="2" intercept="‐1"/>

</feComponentTransfer>

67

feComponentTransfer

<feComponentTransfer>

  <feFuncR type="discrete" tableValues="0 0.5 1"/>

  <feFuncG type="discrete" tableValues="0 0.5 1"/>

  <feFuncB type="discrete" tableValues="0 0.5 1"/>

</feComponentTransfer>

69

feComponentTransfer

<feComponentTransfer>

  <feFuncR type="table" tableValues="1 0"/>

  <feFuncG type="table" tableValues="1 0"/>

  <feFuncB type="table" tableValues="1 0"/>

</feComponentTransfer>

71

feComponentTransfer

<feComponentTransfer>

  <feFuncR

    type="gamma"

    amplitude="2"

    exponent="0.5"

    offset="0.2"

  />

</feComponentTransfer>

73

feColorMatrix

feColorMatrix

| R' |     | a00 a01 a02 a03 a04 |   | R |

| G' |     | a10 a11 a12 a13 a14 |   | G |

| B' |  =  | a20 a21 a22 a23 a24 | * | B |

| A' |     | a30 a31 a32 a33 a34 |   | A |

| 1  |     |  0   0   0   0   1  |   | 1 |

76

feColorMatrix

<feColorMatrix

type="matrix"

values="

  0.343 0.669 0.119 0 0

  0.249 0.626 0.130 0 0

  0.172 0.334 0.111 0 0

  0     0     0     1 0

"/>

77

Умножать на матрицу, что-бысделать картинку чёрно-белой? о_О

<feColorMatrix type="saturate" values="0" />

<feColorMatrix type="saturate" values="4" />

<feColorMatrix type="saturate" values="50" />

<feColorMatrix type="hueRotate" values="0" />

<feColorMatrix type="hueRotate" values="120" />

<feColorMatrix type="hueRotate" values="240" />

<feColorMatrix type="hueRotate" values="320" />

<feColorMatrix type="luminanceToAlpha" />

feConvolveMatrix

feConvolveMatrix

<feConvolveMatrix order="3"

kernelMatrix="1 ‐1  1 ‐1 ‐1 ‐1 1 ‐1 1"/>

 1    ‐1     1

‐1    ‐1    ‐1

1    ‐1     1

91

Classic #selfish #duckface

Fixed #selfish #duckface

<feConvolveMatrix order="3"

kernelMatrix="1 ‐1 1 ‐1 ‐0.1 ‐1 1 ‐1 1"/>

<feConvolveMatrix order="3"

kernelMatrix="9 0 0 0 1 0 0 0 ‐9"/>

<feConvolveMatrix order="3"

kernelMatrix="‐1 ‐1 ‐1 ‐1 7 ‐1 ‐1 ‐1 ‐1"/>

<feConvolveMatrix order="5"

kernelMatrix="1 1 1 1 1 1 ‐2 ‐2 ‐2 1 1 ‐2 0 ‐2 1 1 ‐2 ‐2 ‐2 1 1 1 1 1 1"/>

feComposite

feComposite

<feComposite

    in="source1"

    in2="source2"

    operator="xor"/>

99

over

in

out

atop

xor

arithmetick1="0" k2="1" k3="-1" k4="1"

arithmetick1=".5" k2=".5" k3=".5" k4=".5"

arithmetick1="0" k2="1" k3="1" k4="0"

100

feBlend

feBlend

<feBlend

    in="source1"

    in2="source2"

    mode="lighten"/>

102

Blend modes

normal

screen

multiply

lighten

darken

103

feTile

feTile

<feTile in="source" />

105

feDisplacementMap

feDisplacementMap

109

feDisplacementMap

110

Красный канал. 20 градусов

111

Cиний канал. -20 градусов

112

+ Неподвижный зеленый

113

Happy face

114

Happy face

115

Happy face lvl 40

116

Happy face lvl80

117

Возможностианимации

Синтаксис для SVG анимаций

<feColorMatrix type="saturate" values="0.2">

</feColorMatrix>

119

Синтаксис для SVG анимаций

<feColorMatrix type="saturate" values="0.2">

  <animate attributeName="values" />

</feColorMatrix>

120

Синтаксис для SVG анимаций

<feColorMatrix type="saturate" values="0.2">

  <animate attributeName="values" />

</feColorMatrix>

121

Синтаксис для SVG анимаций

<feColorMatrix type="saturate" values="0.2">

  <animate

    attributeName="values"

    values="0;5;0"

    dur="2s"

    repeatCount="indefinite"/>

</feColorMatrix>

122

Анимация feColorMatrix

123

Анимация feMorphology radius

124

Анимация feDisplacementMap scale

125

Немного хипстерствадля примера

Достоинства SVG-фильтров ипочему мы выбрали их

1.  Быстрые.

2.  Не нужно никаких дополнительных библиотек.

3.  Поддержка разветвленных структур.

4.  Cупер-возможности, огромная спецификация.

5.  Встроенная поддержка анимаций.

6.  Возможность фильтрации картинок с любых

доменов.

138

Недостатки SVG-фильтров

1.  IE10+, встроенный браузер на Android 4.4+

2.  Необходимость вкладывать изображение

внуть SVG

139

SVG-фильтрыдля html

<svg>

  <defs>

    <filter id="f1">

      <feGaussianBlur  stdDeviation="10"/>

    </filter>

  </defs>

</svg>

img {

  ‐webkit‐filter: url(#f1);

  filter: url(#f1);

}

141

<svg>

  <defs>

    <filter id="f1">

      <feGaussianBlur stdDeviation="10 0"/>

    </filter>

  </defs>

</svg>

div {

  ‐webkit‐filter: url(#f1);

  filter: url(#f1);

}

142

Вопросы?