16

If I have an image loaded from an arbitrary URL (local or remote), and do not want to use javascript nor server-side processing, is it possible to sharpen it from client-side with CSS?

Camilo Martin
  • 37,236
  • 20
  • 111
  • 154

2 Answers2

21

Yes, for some browsers this is already possible (like Chrome and Firefox).

In particular, you need mix-blend-mode and CSS filters.

Here's a codepen with the Lenna image as example, and a (compiled) copy of it as a code snippet:

.foo,
.bar,
.bar::after,
.baz {
  width: 512px;
  height: 512px;
  position: absolute;
}
.foo {
  z-index: 1;
  mix-blend-mode: luminosity;
  opacity: 0;
  overflow: hidden;
  -webkit-filter: contrast(1.25);
  filter: contrast(1.25);
}
.foo:hover {
  opacity: 1;
}
.bar,
.bar::after,
.baz {
  background: url(https://upload.wikimedia.org/wikipedia/en/7/7d/Lenna_%28test_image%29.png);
}
.bar::after {
  content: '';
  -webkit-filter: blur(4px) invert(1) contrast(0.75);
  filter: blur(4px) invert(1) contrast(0.75);
  mix-blend-mode: overlay;
}
<div class="foo">
  <div class="bar"></div>
</div>
<div class="baz"></div>

Hover over the image to see the effect. Tweaking of parameters (and maybe using opacity to "fade" the effect, similar to the "intensity" setting of unsharp mask) can help in yielding more desireable results for particular use-cases.

j08691
  • 204,283
  • 31
  • 260
  • 272
Camilo Martin
  • 37,236
  • 20
  • 111
  • 154
  • 1
    This is interesting. However, using CSS filters will severely impact the performance of the browser (just hover on the result image and scroll, and repeat without hovering on image, the effect is evident without having to look at frame rate in diagnostic tool). I think this wouldn't be practical in actual real-world usage in the near future, right? – Billy Apr 13 '15 at 07:25
  • 1
    @Billy Depends - on Chrome I can't even notice that, on Firefox somewhat but only slightly. I can only expect this to get better with time, and "complex" CSS selectors were a performance-killing thing not too long ago, and look where we are now. On the plus side, the radius I chose could be reduced, and if implemented in SVG instead of CSS it *should* be faster because the browser *should* cache the resulting render (but I didn't try it). – Camilo Martin Apr 13 '15 at 07:32
  • 1
    the codepen is missing the image to hover over .. +1 when i used a image to see the effect :) – Jonathan Marzullo Jun 28 '17 at 14:03
  • 1
    Serves me well... I trusted a link shortener! :) – Camilo Martin Jun 29 '17 at 18:15
2

I found a hack that will sharpen downscaled images using CSS. It only works in Chrome, but from my experience Chrome seems to blur images more so than other browsers. This will basically "undo" the blurriness and make the image look more like the original. Layer the image on top of itself using absolute positioning and set image-rendering to pixelated. An example is given here:

Weird CSS hack for sharpening images (Chrome 59 and 60 only)

Ethanoid
  • 69
  • 1
  • 6
  • 2
    That does not make it sharper though, it makes it noisier (almost counts as artificial detail). Nearest neighbor is bad for downscaling because it's unpredictable; consider what it would do to a high-res fabric, by sampling arbitrary pixels instead of an average, thus making a grey fabric look full of noisy black and white dots (also consider: halftone scans). Being able to specify sharper algorithms would be good, in order to increase [acutance](https://en.wikipedia.org/wiki/Acutance). – Camilo Martin Oct 09 '17 at 06:19