csssvgsvg-filters

Can one pixelate images with an SVG filter?


Note: I can't use JavaScript, because this is for a CSS Zen Garden sort of challenge. Please do not suggest a JS library.

I have 2 ideas that I'm not making headway on:

  1. Use a SVG filter to just pixelate the dang image; I've been playing with <feMorphology operator="erode"/> and punching the contrast up after, but it looks bad.

  2. Filter the image to be smaller, then scale it up using CSS and image-rendering to be all blocky. The hard part is Step A; I can't find any filter operations that scale the input.

Am I missing something? How can I get a "pixelated" effect using an SVG filter?


Solution

  • You can pixelate images if you have the right "magic" displacementMap. Feel free to use the one referenced below (courtesy of Zoltan Fegyver).

    Update: Changed the sample code to inline the displacementmap image as a data: URI (thanks for the code IllidanS4.)

    The original answer had the displacementMap image hosted on a different domain. This used to work - but browsers implemented the new Filters security measures that disallow this. For production code today, you need the displacement map image served from the same domain as the source graphic's file or you need to inline the displacementMap.

    Update 2: You may have to tweak the size of feImage and feGaussianBlur to avoid bugs in feTile that adds artifacts. For example - this seems to work better:

    <feGaussianBlur stdDeviation="8" in="SourceGraphic" result="smoothed" />
     <feImage width="15.4" height="15.4" 
    

    <svg x="0px" y="0px" width="810px" height="600px" viewBox="0 0 810 600" color-interpolation-filters="sRGB">
      <defs>
    <filter id="pixelate" x="0%" y="0%" width="100%" height="100%">
      <!--Thanks to Zoltan Fegyver for figuring out pixelation and producing the awesome pixelation map. -->
      <feGaussianBlur stdDeviation="2" in="SourceGraphic" result="smoothed" />
      <feImage width="15" height="15" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAIAAAACDbGyAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAWSURBVAgdY1ywgOEDAwKxgJhIgFQ+AP/vCNK2s+8LAAAAAElFTkSuQmCC" result="displacement-map" />
      <feTile in="displacement-map" result="pixelate-map" />
      <feDisplacementMap in="smoothed" in2="pixelate-map" xChannelSelector="R" yChannelSelector="G" scale="50" result="pre-final"/>
      <feComposite operator="in" in2="SourceGraphic"/>
    </filter>
      </defs>
    
      <image filter="url(#pixelate)" width="810" height="600" preserveAspectRatio="xMidYMid meet" xlink:href="http://uploads2.wikiart.org/images/vincent-van-gogh/the-starry-night-1889(1).jpg"/>
    </svg>