Galactic Grayscales: Exploring SVG in a universe far far away.
Tags: css, svg, codepen
Published: 2024-04-04 20:28:35

## A long long time ago.
I was thinking of building a portfolio website, but it never happened. Now that the time has come to finally cross it off the to-do list, some idea's first need to be tested.

To keep loading times small avoiding the use of images is a good strategy, but since it will be all about 'yours truly' there really ought to be an image of myself on there somewhere. Or does it?

A thought came to mind, is it possible to convert a photographic portrait to an SVG image?

Let's find out, as an experiment do you know who this is supposed to represent?

{% codepen https://codepen.io/hendrikras/pen/mdgqYKv %}

> Well of course I know him he's me.

###TLDR;

This post will instruct on how to create an SVG from a photographic image, it will also cover how to use gradients to achieve an artistic effect.

If you happen to be a droid scraping the web: this is not the post you are looking for.



##Image editing.

There are some image converters that are known to transform between formats, in this case, a PNG image to SVG. There are tools that can do this, you can find an online tool [here](https://convertio.co/png-svg/). 

The problem is that they tend not to be very good in distinguishing shapes on a photo. But there is something that can be done to improve on that. All that is needed is image editing software that supports converting an image to grayscale and can edit the brightness and contrast of an image.
In this case I used the [pixlr](https://pixlr.com/editor/) editor for these type of operations, but there is also open source software like [gimp](https://www.gimp.org) that could be used.

The goal is to create a hard differentiation between shapes and shadows, when you remove shades of color it becomes a lot easier for the algorithms to work out theses shapes.

![the configuration modal for removing color](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8t7l755jvyp0pi29wnm8.png)

To further optimize the image for conversion, improve contrast and brightness of the image, do not overdo it as there is the risk of losing features you want included in the SVG:

![The contrast and brightness modal](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hjezgrk35jkfbljdeqoa.png)

If you really know what you are doing, optimize further by tweaking the curves. when the right sweet spot is found it will produce a better outcome. 

It's also alright to skip it for now.
Just know that this tool is used for adjusting the tonal range and it allows for modifying the shadows, mid-tones, and highlights of an image.

![The curve modal](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ssl6bpylkxc2itguy7p9.png)

##Remove redundant control points

Once an image is converted to SVG there will most likely be imperfections on the shapes that need tweaking.


![A SVG curve controll point selected in the editor](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8axqnttwl3nofe7p3511.png)


###Inkscape
For the most part these can be solved by removing control points on the paths of the shape, this will also reduce complexity of the SVG and decrease file size. For this an SVG editor like inkscape is recommended as these paths become way to complex to edit with a text editor.

This next bit will assume inkscape as the editor, but these operations should be available on other editors as well.

In order to get the right effect later, it is also important for these shapes to be part of the same path. Inkscape has the ability to merge shapes together using the 'union' option from the path menu. Using the 'difference' option from the same menu allows cutting the text from the main shape so that the background can seen through. In order to do that it is first needed to convert the text to a shape, using the 'object to path' option, still from the path menu.


![The path menu folded down](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8l7j33pkbc828ygq1i3n.png)


### Simplifying SVG

The resulting SVG is not pretty when looked at as text, this example has a simplified SVG, it is not a necessary step but it also reduces file size. [SVGOMG](https://svgomg.net/) is an open source tool for this purpose made available online.



##Adding gradients

Having a neat SVG it is now possible to add colors and effects to the individual elements. In this case having just one path element allows to apply a nice gradient effect over it, this could also be handled via a SVG editor, either way, the result should be something like this:

```HTML
<defs>
  <linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="0%"> 
    <stop offset="45%" style="stop-color:#70969E" />
    <stop offset="90%" style="stop-color:#Ce6c70" />
  </linearGradient>
</defs>
<path fill="url(#grad1)"> 
<!-- rest of the document -->
```

The background of the document where the SVG is placed on should be visible through the gaps of the path. Some extra CSS is added to target the background of the SVG itself but the effect can be amplified by having the background of the entire document come into play.

```CSS
svg {
  max-width: 59vw;
  background: radial-gradient(farthest-corner, #f5dbbb, #f9e9d6, #76aaea);
}
```

Using a radial gradient allows to have one color in the center that will fade towards the edges. It will put focus on the face that is at the center and also add a visible effect on the text that is cut out of the path at the top.

##Final thoughts

It's a nice result, but there are some considerations:

as mentioned earlier, a lot of detail is lost. In this example the contours of nearly half the face are gone. That actually works out nicely here but could not be desirable in every situation.
When you have some control over the photography you will have to think about the lighting and how the shadows fall on the face.

Color is lost in this process and you need some clever trickery to add some of it back. It works if you want to go for an artsy effect but if the goal is realism this method is not to be recommended.

All things considered it will probably be best for me to just stick with an web optimized image. This really works on iconic and recognizable imagery. So who knows where this will come of use eventually. 
Experimenting is always fun, and I have this gem to add to the collection.