обнаружение края в фильтре svg

Я пытаюсь найти краевые точки изображения с помощью фильтра SVG. Проблема не в том, чтобы добиться успеха. Ниже приведен код, который я пробовал.

<svg width="100%" height="495">
 <defs>
   <filter id="blobby" color-interpolation-filters="sRGB">
   <feColorMatrix type="saturate" values="0"/>
    <feComponentTransfer>
        <feFuncR type="discrete" tableValues="0 0 0 0 0 1"/>
        <feFuncG type="discrete" tableValues="0 0 0 0 0 1"/>
        <feFuncB type="discrete" tableValues="0 0 0 0 0 1"/>
      </feComponentTransfer>
      <feMorphology operator="erode" radius="0"/>
      <feGaussianBlur stdDeviation="10"/>
      <feComponentTransfer>
        <feFuncR type="discrete" tableValues="0 0 0 0 0 1"/>
        <feFuncG type="discrete" tableValues="0 0 0 0 0 1"/>
        <feFuncB type="discrete" tableValues="0 0 0 0 0 1"/>
      </feComponentTransfer>
    </filter>
  </defs>
<g filter="url(#blobby)">
 <image xlink:href="https://i.stack.imgur.com/dreFV.jpg" />
</g>
</svg>

Если я помещу тег изображения вне svg, он сработает. Но таким образом я не смог сохранить svg, когда у него есть html. А также мне не нужен этот формат. Я хочу иметь вышеуказанный формат svg.

img {
  width: 400px;
  
}

.blob {
  background-color: white;
  padding: 40px;
  filter: url(#blobby);
}

/* Hide the SVG element */
svg {
  width: 0px;
  height: 0px;
  position: absolute;
  left: -999px;
}
<svg>
  <defs>
    <filter id="blobby" color-interpolation-filters="sRGB">
      <!-- Convert to greyscale -->
      <feColorMatrix type="saturate" values="0"/>
      <!-- Threshhold to black or white -->
      <feComponentTransfer>
        <feFuncR type="discrete" tableValues="0 0 0 0 0 1"/>
        <feFuncG type="discrete" tableValues="0 0 0 0 0 1"/>
        <feFuncB type="discrete" tableValues="0 0 0 0 0 1"/>
      </feComponentTransfer>
      <!-- Morphology filter to "erode" (shrink) the white areas -->
      <feMorphology operator="erode" radius="8"/>
      <!-- Blur to cause image to "spread" -->
      <feGaussianBlur stdDeviation="10"/>
      <!-- High contrast to threshhold again -->
      <feComponentTransfer>
        <feFuncR type="discrete" tableValues="0 0 0 0 0 1"/>
        <feFuncG type="discrete" tableValues="0 0 0 0 0 1"/>
        <feFuncB type="discrete" tableValues="0 0 0 0 0 1"/>
      </feComponentTransfer>
    </filter>
  </defs>
  <g>
    <img src="https://s3-us-west-2.amazonaws.com/fabric-canvas/Bros-1.jpg"/>
    <br>
    <div class="blob">
      <img src="https://s3-us-west-2.amazonaws.com/fabric-canvas/Bros-1.jpg"/>
    </div>
  </g>
</svg>

Ожидаемый результат:

Заранее спасибо.


person lalithkumar    schedule 24.10.2017    source источник


Ответы (1)


Мы можем получить желаемый конечный результат, используя еще несколько фильтрующих элементов.

img {
  width: 400px;
  
}

.blob {
  background-color: white;
  padding: 40px;
  filter: url(#blobby);
}

/* Hide the SVG element */
svg {
  width: 0px;
  height: 0px;
  position: absolute;
  left: -999px;
}
<svg>
  <defs>
    <filter id="blobby" color-interpolation-filters="sRGB">
      <!-- Convert to greyscale -->
      <feColorMatrix type="saturate" values="0"/>
      <!-- Threshhold to black or white -->
      <feComponentTransfer>
        <feFuncR type="discrete" tableValues="0 0 0 0 0 1"/>
        <feFuncG type="discrete" tableValues="0 0 0 0 0 1"/>
        <feFuncB type="discrete" tableValues="0 0 0 0 0 1"/>
      </feComponentTransfer>
      <!-- Morphology filter to "erode" (shrink) the white areas -->
      <feMorphology operator="erode" radius="8"/>
      <!-- Blur to cause image to "spread" -->
      <feGaussianBlur stdDeviation="10"/>
      <!-- High contrast to threshhold again -->
      <!-- But this time we switch black and white as we -->
      <!-- will use this as an alpha mask in the next steps -->
      <!-- We only need one channel here -->
      <feComponentTransfer>
        <feFuncR type="discrete" tableValues="1 1 1 1 1 0"/>
      </feComponentTransfer>
      <!-- Convert the the red channel of this to an alpha channel -->
      <!-- The result is a black shape with an alpha mask of the right shape -->
      <feColorMatrix type="matrix" result="alpha-mask" values="0 0 0 0 0  0 0 0 0 0  0 0 0 0 0 1 0 0 0 0"/>
      <!-- Create a blank white rectangle -->
      <feFlood flood-color="white" result="white-flood"/>
      <!-- Layer 1: Mask the blank white fill with the alpha mask we created earlier -->
      <feComposite in="white-flood" in2="alpha-mask" operator="in" result="masked-white"/>
      <!-- Layer 2: Grow the black shape to create our black outline "stroke" -->
      <feMorphology in="alpha-mask" operator="dilate" radius="1" result="black-stroke"/>
      <!-- Layer 3: Create a shadow to go at the back -->
      <feGaussianBlur in="alpha-mask" stdDeviation="10"/>
      <feOffset dx="5" dy="5" result="offset-blur"/>
      <feFlood flood-color="#000" flood-opacity="0.6"/>  <!-- Lighten the shadow a little -->
      <feComposite in2="offset-blur" operator="in" result="shadow"/>
      <!-- Merge the three layers together -->
      <feMerge>
        <feMergeNode in="shadow"/>
        <feMergeNode in="black-stroke"/>
        <feMergeNode in="masked-white"/>
      </feMerge>
    </filter>
  </defs>
  <g>
    <img src="https://s3-us-west-2.amazonaws.com/fabric-canvas/Bros-1.jpg"/>
    <br>
    <div class="blob">
      <img src="https://s3-us-west-2.amazonaws.com/fabric-canvas/Bros-1.jpg"/>
    </div>
  </g>
</svg>

person Paul LeBeau    schedule 25.10.2017
comment
Спасибо, Пол ... но div не должен быть внутри svg. Возможно ли получить тот же результат, используя тег изображения svg? - person lalithkumar; 25.10.2017
comment
когда я сохраняю это как svg, он должен показать ожидаемый результат. а> - person lalithkumar; 25.10.2017
comment
При использовании такого фильтра вам, вероятно, потребуется встроить его в свою страницу. Я не уверен, насколько надежно браузеры обрабатывают фильтры во внешних документах. Если вы все равно хотите попробовать, вам нужно добавить объявление XML в файл, чтобы сделать его действительным документом SVG. - person Paul LeBeau; 25.10.2017
comment
я пробовал с <svg version="2.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> этими атрибутами пространства имен. Но когда я добавляю, он отображается пустым и не показывает никаких ошибок - person lalithkumar; 25.10.2017
comment
SVG версии 2.1 не существует. Попробуйте 1.1. И под XML-декларацией я имел в виду строку: <?xml version="1.0" encoding="utf-8"?>, которая требуется для всех XML-файлов. Для получения дополнительной информации см. ссылку, которую я разместил. - person Paul LeBeau; 25.10.2017
comment
извините, я пробовал только с 1.1 .. затем я просто изменил и протестировал .. а также добавил <?xml version="1.0" encoding="utf-8" standalone="no"?> это уже, как вы упомянули .. без изменений - person lalithkumar; 25.10.2017
comment
это моя скрипка.. она работает здесь.. но когда я сохраняю как svg, это не так Работа.. - person lalithkumar; 25.10.2017
comment
<div> не является допустимым элементом SVG. Как и <img>. SVG-эквивалентом <img> является элемент <image>. - person Paul LeBeau; 25.10.2017
comment
Да, если я изменю img на тег изображения, фильтр не будет работать ... не могли бы вы обновить ответ с помощью тега изображения - person lalithkumar; 26.10.2017
comment
ТАК. не является сервисом написания кода. Я думаю, пришло время вам сделать часть работы самостоятельно. Изучите, как работает элемент <image>. - person Paul LeBeau; 26.10.2017
comment
На самом деле я новичок в этом. Последние два дня я пытался, но не получил ожидаемого результата с тегом изображения. А также в самом вопросе я сказал, что хочу с тегом изображения. это то, что я попросил о помощи ... если вы поделитесь со мной любой ссылкой, я буду признателен, и это мне очень поможет .. спасибо - person lalithkumar; 26.10.2017