Transparent JPG (With SVG)

Let’s say you have a photographic image that really should be a JPG or WebP, for the best file size and quality. But what if I need transparency too? Don’t I need PNG for that? Won’t that make for either huge file sizes (PNG-24) or weird quality (PNG-8)? Let’s look at another way that ends up best-of-both-worlds.

https://cdn.css-tricks.com/wp-content/uploads/2017/02/orig-300x212.jpg 300w, https://cdn.css-tricks.com/wp-content/uploads/2017/02/orig-768x542.jpg 768w, https://cdn.css-tricks.com/wp-content/uploads/2017/02/orig-1024x722.jpg 1024w" alt="" src="https://cdn.css-tricks.com/wp-content/uploads/2017/02/orig.jpg">
The original photographic image.

The goal is to clip myself out of the image, removing the background. My technique for that is usually to use Photoshop and cut a clipping path manually with the Pen tool.

https://cdn.css-tricks.com/wp-content/uploads/2017/02/clip-path-300x279.jpg 300w, https://cdn.css-tricks.com/wp-content/uploads/2017/02/clip-path-768x715.jpg 768w" alt="" src="https://cdn.css-tricks.com/wp-content/uploads/2017/02/clip-path.jpg">

Now I can select the inverse of that clipping path to easily remove the background.

Attempting to save this as a 1200px wide image as PNG-24 out of Photoshop ends up as about a 1MB image!

https://cdn.css-tricks.com/wp-content/uploads/2017/02/too-big-300x198.jpg 300w, https://cdn.css-tricks.com/wp-content/uploads/2017/02/too-big-768x507.jpg 768w, https://cdn.css-tricks.com/wp-content/uploads/2017/02/too-big-1024x676.jpg 1024w" alt="" src="https://cdn.css-tricks.com/wp-content/uploads/2017/02/too-big.jpg">
1MB is huge 🙁

We could cut that by 75% using PNG-8, but then we 1) get that weird Giffy look (less photographic) and 2) have to pick a matte color for the edges because we aren’t getting nice alpha transparency here, just binary transparency.

https://cdn.css-tricks.com/wp-content/uploads/2017/02/png8-284x300.jpg 284w, https://cdn.css-tricks.com/wp-content/uploads/2017/02/png8-768x811.jpg 768w" alt="" src="https://cdn.css-tricks.com/wp-content/uploads/2017/02/png8.jpg">
Much better file size, but quality is weird.

Gosh what if we could just use JPG? The quality and file size is way better.

https://cdn.css-tricks.com/wp-content/uploads/2017/02/jpg-267x300.jpg 267w, https://cdn.css-tricks.com/wp-content/uploads/2017/02/jpg-768x863.jpg 768w" alt="" src="https://cdn.css-tricks.com/wp-content/uploads/2017/02/jpg.jpg">

No transparency though.

But wait! Can’t we just clip this thing out? We have clip-path now. Well… yeah. We do have clip-path. It can’t take a path(), though, and what we’ve created for vector points in Photoshop is path data. It could take a polygon() though, if we made all the lines straight. That’s probably not ideal (I’m curvy!). Or we could make a <clipPath> element in some inline SVG and use clip-path: url(#id_of_clipPath);, which does support a <path> inside.

There is masking as well, which is another possibility.

Let’s look at a third possibility though: put everything into <svg>. That made some logical sense to me, so all this stays together and scales together.

The trick is to make two things:

  1. The JPG
  2. The clipping <path>

The JPG is easy enough. Output that right from Photoshop. Optimize.

Now we can set up the SVG. SVG is happy to take a raster graphic. SVG is known for vector graphics, but it’s a very flexible image format.

<svg>
  <image xlink:href="/images/chris.jpg" x="0" y="0">
<svg>

To get the path, we export the path we created with the Pen tool over to Illustrator.

https://cdn.css-tricks.com/wp-content/uploads/2017/02/paths-to-illustrator-262x300.jpg 262w, https://cdn.css-tricks.com/wp-content/uploads/2017/02/paths-to-illustrator-768x879.jpg 768w, https://cdn.css-tricks.com/wp-content/uploads/2017/02/paths-to-illustrator-895x1024.jpg 895w" alt="" src="https://cdn.css-tricks.com/wp-content/uploads/2017/02/paths-to-illustrator.jpg">

Now we have the path over there, and it’s easy to export as SVG:

https://cdn.css-tricks.com/wp-content/uploads/2017/02/clip-from-ai-300x284.jpg 300w, https://cdn.css-tricks.com/wp-content/uploads/2017/02/clip-from-ai-768x727.jpg 768w, https://cdn.css-tricks.com/wp-content/uploads/2017/02/clip-from-ai-1024x970.jpg 1024w" alt="" src="https://cdn.css-tricks.com/wp-content/uploads/2017/02/clip-from-ai.jpg">

Now we have the path data we need:

https://cdn.css-tricks.com/wp-content/uploads/2017/02/path-data-300x117.jpg 300w, https://cdn.css-tricks.com/wp-content/uploads/2017/02/path-data-768x299.jpg 768w, https://cdn.css-tricks.com/wp-content/uploads/2017/02/path-data-1024x399.jpg 1024w" alt="" src="https://cdn.css-tricks.com/wp-content/uploads/2017/02/path-data.jpg">
Even with all those points, this was 1.5K unoptimzed and ungzipped. Not much overhead.

Let’s use that <path> within a <clipPath> in the SVG we’ve started. Then also apply that clip path to the <image>:

<svg viewBox="0 0 921.17 1409.71">
  <defs>
    <clipPath id="chris-clip">
      <path d=" ... " />
    </clipPath>
  </defs>
  <image xlink:href="/images/chris.jpg" clip-path="url(#chris-clip)" x="0" y="0" width="921" height="1409">
<svg>

Tada!

A transparent JPG, essentially.


Transparent JPG (With SVG) is a post from CSS-Tricks

Read Full Article from CSS Tricks https://css-tricks.com/transparent-jpg-svg/