Editing images using SVG in a text editor

Using SVG to edit pictures from a text editor

Jul 17 2024

Recently I tasked myself with coming up with a new profile picture. I stumbled across a popular service called Profile Pic Maker. It is a free browser tool for creating good-looking profile pictures for your social accounts etc.. When I started using it I really liked the results, but noticed that I could safe the pictures only in low resolution. That's when the idea came to re-create the result with tools I have access to.

The goal was to come up with something like this:

Profile picture example

Choosing the right tools

If you know a popular tool like Photoshop or any other advanced Photo editor the result would be trivially easy, but not for me, as I don't know these tools. I'll just be honest about that... Learning those tools would also take some time after all.

Right off the bat, cutting out the face from the background was done using an external service. This process could also be automated in the future by using an API, but honestly this was just laziness on my part - I liked the quality of the external face-cut-out much better than what I would have accomplished with Open Source tools. But, as soon I had the picture of myself without a background I turned towards the command line.

Imagemagick

My first hunch was to use Imagemagick. This is a fantastic tool for image editing, and I believe many Open Source Photo editors use it as a backend. By the way, I have already written a post about how to edit video's from a Text Editor, so the idea was not completely new. With Imagemagick you can overlay pictures on top of each other without problem:

magick composite -compose atop top-layer.png bottom-layer.png result.png

You can even draw layers using Imagemagick. Theoretically you could create new images from scratch using a bash script.

However, when I started experimenting with Imagemagick I looked into creating cut-outs in svg (in order to overlay them with Imagemagick). I have to admit at this point, that I have a soft spot for SVG, after all I created the logo's for my websites in it. And with created I mean that I literally wrote the SVG code in a Text Editor.

That's when I thought: Why don't I create the whole picture in SVG and then export it using Imagemagick?

SVG as a Photo Editor

You can open and preview a .svg file in a browser, making it very easy to preview changes. And the main thing that makes the SVG format very flexible is the fact that you can import pictures into it like so:

<image x="0" y="0" width="800" height="800" xlink:href="./background_removed.png" />

With that, creating layers is very easy, as the file is parsed from top to bottom (akin to HTML) you can easily determine what will be on top and what will be behind.

The example picture above can thus be created with three layers:

  1. Background layer
  2. Person cut-out
  3. Mask layer (to hide the bottom part of the body)

Creating the background circle is trivially easy, and overlaying the picture can be done with the previous command. The third layer was drawn by hand, by calculating the points. It sounds complicated, but no visual editor is necessary, once you are familiar with the SVG path syntax. You can also set the view-port, resolution and everything else you would do with a "normal" Photo Editor.

SVG Code

The final code (for the example picture above) looked something like this:

<svg width="1192px" height="1192px" fill="none" viewBox="0 0 1192 1192" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">

<!-- White background -->
<rect x="0" y="0" width="1192" height="1192" fill="#FFFFFF"></rect>
<!-- Colored circle -->
<circle cx="596" cy="596" r="442" fill="#ED6337"/>
<!-- Cutout image overlay -->
<image x="0" y="0" width="1192" height="1192" xlink:href="./background_removed.png" />
<!-- Bottom overlay -->
<path d="M 0 596 L 154 596 A 442 442 0, 0, 0, 1038 596 L 1192 596 L 1192 1193 L 0 1193 Z" fill="#FFFFFF"/>
</svg>

I have commented the separate layers. In the next example you can achieve the same result but this time with SVG masks. This allows the background to be transparent, useful when converting to a png with a transparency layer. While this is a little bit more complicated, this also allows for way more flexibility.

<svg width="1192px" height="1192px" fill="none" viewBox="0 0 1192 1192" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">

<!-- Background (removed for transparency) -->
<!-- <rect x="0" y="0" width="1192" height="1192" fill="#FFFFFF"></rect> -->

<!-- Mask Definitions
     white = visible; 
     black = invisible (cutout)
-->
<mask id="back-mask">
<rect x="0" y="0" width="1192" height="1192" fill="white"></rect>
<path d="M 0 596 L 154 596 A 442 442 0, 0, 1, 1038 596 L 1192 596 L 1192 0 L 0 0 L 0 596 L 154 596 A 442 442 0, 0, 0, 1038 596 L 1192 596 L 1192 1193 L 0 1193 Z" fill="black" />
</mask>

<mask id="front-mask">
<rect x="0" y="0" width="1192" height="1192" fill="white"></rect>
<path d="M 0 596 L 154 596 A 442 442 0, 0, 0, 1038 596 L 1192 596 L 1192 1193 L 0 1193 Z" fill="black"/>
</mask>

<!-- Apply masks to both layers -->
<rect x="0" y="0" width="1192" height="1192" fill="#ED6337" mask="url(#back-mask)"></rect>
<image x="0" y="0" width="1192" height="1192" xlink:href="./background_removed.png" mask="url(#front-mask)"/>

</svg>

I can assure you, all of the code has been written by hand without any designer software. Thus, in this workflow, I have treated the SVG format itself as a designer software, akin to how you would design a simple website manually with HTML and CSS. In principle this doesn't differ from that.

Converting SVG to PNG

The last step that has to be done - once you are happy with the result - is to convert it back to a .jpg or .png. Unfortunately, Imagemagick didn't support embedding an external picture, so I had to revert to Inkscape just for this final step. Maybe there are other tools available to do this more comfortably through the CLI, let me know.

Advantages of this system

Let's have a look at the advantages of using this workflow.

Automating the process

One main thing, is that you can change the final picture trivially easy: Do you want to change the color? A different background shape or a different face-picture? Change the background, aspect-ration or resolution?

All of this can be done by changing just a single line in your favorite text editor!

Version controlling ... an image

For bigger projects, next to using your favorite text editor, you can also use all the other tools you prefer, such as version control (git). Yes indeed, you can thus version control your image, especially when you have written good code. It so easy to plug this in into an automatizing pipeline, so that you can create your own service for Profile Picture generation.

This is the big advantage when you know tools like this.

Disadvantages

Of course, this system has also disadvantages, especially when you are not familiar with the technologies under the hood. Also, things like prototyping and previewing designs is maybe more slow. Creating complicated designs is also a mess, even though this strongly depends on the way you architect your project.

In any case, this has been an interesting experiment. There is something liberating to do it in this way. You have more control about your result, you are super-flexible and use end up using only free (Open Source) technologies. You are limited only by your imagination by what you can create this way.

And you can easily integrate this workflow into other project, for yourself or for commercial reason.

Feel free to contact me if you have (critical) thoughts and ideas - those are always welcome.