Efficient Logo Generation with Fabric, DALL‑E, and Vectorization Tools

The image features an intricate and colorful design that incorporates various artistic elements. Dominant swirls of vibrant colors intertwine with patterns resembling musical notes and geometric shapes. There is a stylized bird in the lower left corner, and elements related to design, such as a keyboard, a palette, colored pencils, and paper. The background has an aged parchment appearance, enhancing the overall artistic and creative theme of the composition.

Introduction

After explain­ing a straight­for­ward work­flow for cre­at­ing an arti­cle image in the post Fast and Easy Image Gen­er­a­tion with Fab­ric and Ope­nAI, an addi­tion­al step can be incor­po­rat­ed into such a work­flow. In this post, I would like to demon­strate how a brief descrip­tion can be trans­formed into a freely scal­able logo in SVG for­mat using Fab­ric, DALL‑E, and vec­tor­iza­tion tools.
SVG for­mat, uti­liz­ing Fab­ric, DALL‑E, and com­mand-line vec­tor­iza­tion tools.

Prerequisites

As out­lined in the pre­vi­ous arti­cle, the fol­low­ing pre­req­ui­sites must be met:

Addi­tion­al­ly, the fol­low­ing com­mand-line pro­grams are required for this work­flow:

  • Auto­trace: Con­verts sim­ple bitmaps into vec­tor graph­ics and sup­ports col­ors.
  • Potrace: Trans­forms mono­chrome bitmaps into more pre­cise vec­tor graph­ics.
  • ImageMag­ick: A pow­er­ful com­mand-line graph­ic tool, uti­lized here for con­vert­ing bitmap graph­ics.

I employ Auto­trace and Potrace for the cre­ation of vec­tor graph­ics, as they yield dif­fer­ent results. More on that below.

All these pro­grams can be eas­i­ly installed on a Mac using Home­brew:

brew install jq autotrace potrace imagemagick

The Workflow

As with most work­flows involv­ing Fab­ric, this one begins with a text input, which may be pro­vid­ed either as a text file or a sim­ple string, depend­ing on the com­plex­i­ty of the descrip­tion. This input is then processed by Fab­ric along with a spe­cial­ized pat­tern opti­mized for logo cre­ation. The result is a prompt which will be passed to a script that invokes DALL‑E with that prompt, saves the gen­er­at­ed logo as PNG, and for­wards its path to the next script. This sub­se­quent script then con­verts the PNG into a vec­tor-based SVG file.

The Logo Pattern

With the instal­la­tion of Fab­ric, a pat­tern specif­i­cal­ly opti­mized for logo cre­ation is already avail­able: create_logo. I dupli­cat­ed this fold­er in the Pat­terns direc­to­ry, renam­ing it to create_mylogo, and replaced the con­tent of the includ­ed system.md with the fol­low­ing:

# IDENTITY and PURPOSE

You create simple, elegant, and impactful company logos based on the input given to you. The logos are super minimalist, minimal colors.

Take a deep breath and think step by step about how to best accomplish this goal using the following steps.

# OUTPUT SECTIONS

- Output a prompt that can be sent to an AI image generator for a simple and elegant logo that captures and incorporates the meaning of the input sent. 
- The prompt should take the input and create a simple, vector graphic logo description for the AI to generate. 
- This logo should be optimal for convert it with potrace. Only white backgound. No Colors, No Text.
- Make an very detailed description with 100 words


# OUTPUT INSTRUCTIONS

- Ensure the description asks for a simple, vector graphic logo with a white background.
- Ensure the description asks for minimalist vector graphic logo. 
- Ensure the description asks for a design that emphasizes smooth curves and geometric shapes.
- Ensure the description asks for an entirely in black on a white background.
- Ensure the description asks for stylized form of all objects. 
- Do not output anything other than the raw image description that will be sent to the image generator.
- You only output human-readable Markdown.
- Do not output warnings or notes —- just the requested sections.

# INPUT:

INPUT:

This file can be tai­lored and fur­ther opti­mized to meet indi­vid­ual require­ments. Hav­ing pre­pared the pat­tern, we now pro­ceed to the next step: the actu­al cre­ation of the logo.

The CreateLogo Script

This script takes the prompt from Fab­ric and pass­es it to DALL‑E via the Ope­nAI API. Ini­tial­ly, I intend­ed to invoke DALL‑E 2 at a size of 512x512 for logo cre­ation, as this would make image gen­er­a­tion some­what more cost-effec­tive. How­ev­er, I was ulti­mate­ly con­vinced by the supe­ri­or inter­pre­ta­tion of the prompt and the qual­i­ty of the results to gen­er­ate the logos using DALL‑E 3 instead.

Over­all, the script close­ly resem­bles the script for arti­cle image gen­er­a­tion from the pre­vi­ous arti­cle, with the only dif­fer­ence being the use of a square for­mat of 1024x1024 for the image size. The cre­at­ed logos are also stored in a dif­fer­ent fold­er. At the end of the script, I have com­ment­ed out the lines for sav­ing the prompts. If these are to be retained for opti­miz­ing the pat­tern, the com­ment sym­bol must be removed from those lines. It is impor­tant to note that the script only out­puts the path of the cre­at­ed PNG file!

As always, I save the script in the $HOME/Applications/ fold­er under the name CreateLogo and mark it as exe­cutable with:

chmod +x $HOME/Applications/CreateLogo

And here is the script:

#!/bin/zsh

# Check if data is piped into the script
if [ -t 0 ]; then
  # Check if data is piped into the script
  exit 1
else
  # Read all piped inputs
  prompt=$(cat -)
fi

# The OpenAI API key should be set as an environment variable
api_key="$OPENAI_API_KEY"

# Create JSON payload
json_payload=$(jq -n \
  --arg model "dall-e-3" \
  --arg prompt "$prompt" \
  --argjson n 1 \
  --arg size "1024x1024" \
  '{model: $model, prompt: $prompt, n: $n, size: $size}'
)

# Get the current date and time for the filename
timestamp=$(date +"%Y%m%d_%H%M%S")

# Execute the curl command and save the response
response=$(curl -s https://api.openai.com/v1/images/generations \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $api_key" \
  -d "$json_payload")

# Extract the image URL from the response
image_url=$(echo $response | jq -r '.data[0].url')


# Save the image with date and time in the filename
curl -s "$image_url" -o "$HOME/Pictures/CreateLogo/image_${timestamp}.png"

# Extract the revised prompt from the response
# revised_prompt=$(echo $response | jq -r '.data[0].revised_prompt')
# echo "$revised_prompt" > "$HOME/Pictures/CreateLogo/revised_prompt_${timestamp}.txt"
# echo "Revised prompt has been saved as prompt_${timestamp}.txt"

# Save the prompt created by Fabric in a text file
# echo "$prompt" > "prompt_${timestamp}.txt"
# echo "Prompt has been saved as prompt_${timestamp}.txt"

# Output success message
echo $HOME/Pictures/CreateLogo/image_${timestamp}.png

# Open the image
# open image_${timestamp}.png

Vectorization

As pre­vi­ous­ly men­tioned, I uti­lize two dis­tinct com­mand-line tools in this exam­ple to han­dle the con­ver­sion from PNG to the vec­tor for­mat SVG. Inter­est­ing­ly, I have only found these two tools, which are quite dat­ed. There are sev­er­al AI-based ser­vices avail­able online, but they do not nec­es­sar­i­ly pro­vide an API and can be rather expen­sive.

Both pro­grams are com­mand-line tools, but they can­not be eas­i­ly inte­grat­ed into a Fab­ric work­flow, as they do not accept the stan­dard input. There­fore, I have encap­su­lat­ed them in scripts that take the file path of the PNG, ini­ti­ate the pro­cess­ing, and then name the SVG accord­ing­ly.

The Autotrace Script

The script first checks whether a file has been pro­vid­ed, ver­i­fies the path, and ensures that it is indeed a PNG file. While this may not be cru­cial for the Fab­ric work­flow, it is ben­e­fi­cial to have some error checks in place if the script is used “stand­alone.” In prin­ci­ple, Auto­trace can process oth­er bitmap for­mats as well, but since Ope­nAI gen­er­ates PNG files, I restrict the script to this for­mat.

After the checks, the path to the file and the name are sep­a­rat­ed, allow­ing the SVG to be saved under the same path and name, but with the .svg exten­sion. The Auto­trace tool is then invoked with the path of the PNG file and sev­er­al options, and the SVG is saved. I have yet to sys­tem­at­i­cal­ly exper­i­ment with the options, as there is cer­tain­ly poten­tial for improved results.

#!/bin/bash

# Check if data has been passed through the pipe
if [ -t 0 ]; then
    echo "Keine Datei übergeben."
    exit 1
fi

# Read the filename from standard input
read -r input_file_path

# Check if the file path is empty or the file does not exist
if [ -z "$input_file_path" ] || [ ! -f "$input_file_path" ]; then
    echo "Ungültiger Dateipfad: $input_file_path"
    exit 1
fi

# Check if the file is a PNG file
if [[ "$input_file_path" != *.png ]]; then
    echo "Die Datei ist keine PNG-Datei."
    exit 1
fi

# Extract the input filename without path and extension
input_filename=$(basename "$input_file_path")
input_basename="${input_filename%.*}"

# Determine the directory of the input file
input_dir=$(dirname "$input_file_path")

# Set the output file path
output_file="$input_dir/$input_basename.svg"


# Call autotrace with the specified parameters
if ! autotrace "$input_file_path" \
    --output-file "$output_file" \
    --input-format png \
    --output-format svg \
    --color-count 256 \
    --background-color FFFFFF \
    --despeckle-level 20 \
    --remove-adjacent-corners \
    --corner-threshold 0.5 \
    --line-threshold 1; then
    echo "Fehler bei der Konvertierung mit autotrace."
    exit 1
fi

open $output_file

This script will be saved as svgAuto in the $HOME/Applications folder and marked as exe­cutable.

Now the script can be test­ed. The echo com­mand is used since the path, not the con­tent of the PNGs, is being passed.

echo /path/to/logo.png | svgAuto

Here is an exam­ple with the source image logo.png:

The image features two stylized birds in the foreground, depicted in white with turquoise accents. Behind them, there are two abstract representations of tall buildings with vertical stripes, also in turquoise. The overall design has a clean, modern look.

And her the SVG con­vert­ed by Auto­trace:

The SVG Versions of the image that features two stylized birds in the foreground, depicted in white with turquoise accents. Behind them, there are two abstract representations of tall buildings with vertical stripes, also in turquoise. The overall design has a clean, modern look.

The result is not bad, but it does not close­ly match the orig­i­nal con­tours. Adjust­ing the val­ues of the options or uti­liz­ing addi­tion­al options could lead to improve­ments. More options and fur­ther infor­ma­tion can be eas­i­ly accessed in the ter­mi­nal using the com­mand man autotrace.

The Potrace Script

Potrace can only cre­ate mono­chrome vec­tor files. It oper­ates on grayscale or col­ored bitmaps using thresh­olds that may need to be adjust­ed based on the type of image. How­ev­er, I have found the default set­tings, as used in the script, to be suf­fi­cient thus far. Inter­est­ing­ly, Inkscape also uti­lizes Potrace for vec­tor­iza­tion but can process col­ored bitmaps as well. As far as I under­stand, it vec­tor­izes the image in mul­ti­ple pass­es with dif­fer­ent thresh­olds and then recon­structs the cre­at­ed SVGs at the end. For my pur­pos­es, the mono­chro­mat­ic out­put is ade­quate. Addi­tion­al options for Potrace can also be accessed in the ter­mi­nal using man potrace.

The script that works with the Potrace pro­gram func­tions sim­i­lar­ly to the one with Auto­trace. The first part is iden­ti­cal. The file path is passed using echo, parsed, and then used to save the SVG file in the cor­rect loca­tion with the appro­pri­ate name.

Before Potrace is invoked, the orig­i­nal PNG image is first con­vert­ed to the PGM for­mat using the com­mand magick, which was installed with ImageMag­ick, since Potrace can­not process PNG files. After that, Potrace is called with sev­er­al options that can also be opti­mized or sup­ple­ment­ed, just like in the Auto­trace script.

#!/bin/bash

# Check if data has been passed through the pipe
if [ -t 0 ]; then
    echo "Keine Datei übergeben."
    exit 1
fi

# Read the file path from standard input
read -r input_file_path

# Verify if the file path is empty or if the file does not exist
if [ -z "$input_file_path" ] || [ ! -f "$input_file_path" ]; then
    echo "Ungültiger Dateipfad: $input_file_path"
    exit 1
fi

# Check if the file is a PNG file
if [[ "$input_file_path" != *.png ]]; then
    echo "Die Datei ist keine PNG-Datei."
    exit 1
fi

# Determine the directory and filename of the input file without extension
input_dir=$(dirname "$input_file_path")
input_basename=$(basename "$input_file_path" .png)

# Create the PGM output path
output_pgm_path="$input_dir/$input_basename.pgm"

# Create the SVG output path
output_svg_path="$input_dir/$input_basename.svg"

# Step 1: Convert PNG to PGM using ImageMagick

magick "$input_file_path" "$output_pgm_path"
if [ $? -ne 0 ]; then
    echo "Fehler bei der Konvertierung von PNG zu PGM."
    exit 1
fi

# Step 2: Convert PGM to SVG using 'potrace' with the specified options
if ! potrace "$output_pgm_path" \
    --svg \
    --output="$output_svg_path" \
    --turdsize 2 \
    --turnpolicy black \
    --alphamax 1 \
    --opttolerance 0.2; then
    echo "Fehler bei der Konvertierung mit potrace."
    exit 1
fi

# Successful conversion
echo $output_svg_path

# Clean up the temporary file
rm "$output_pgm_path"

exit 0

The result of vec­tor­iza­tion with Potrace of the pre­vi­ous­ly used orig­i­nal PNG appears as fol­lows (con­sid­er tem­porar­i­ly dis­abling dark mode if only a black area is vis­i­ble):

Converted Image to SVG: The image features two stylized birds in the foreground, depicted in white with turquoise accents. Behind them, there are two abstract representations of tall buildings with vertical stripes, also in turquoise. The overall design has a clean, modern look.

The SVG con­vert­ed by Potrace has traced the con­tours much more accu­rate­ly than Auto­trace. Fur­ther­more, the paths can be edit­ed more effec­tive­ly in pro­grams such as Inkscape or Affin­i­ty Design­er. If you are in dark mode, you may see noth­ing due to the fact that the above SVG is trans­par­ent. There should actu­al­ly be an option in Potrace that fills the back­ground, but it some­how did not work for me. How­ev­er, there is a solu­tion, as SVG is an XML text for­mat, allow­ing for rel­a­tive­ly easy inser­tion of a def­i­n­i­tion that ensures the back­ground turns white. The head­er sec­tion of the SVG file must be sup­ple­ment­ed with the line

<rect width="100%" height="100%" fill="white"/>

before the <metadata> tag. This can be accom­plished, if desired, by the fol­low­ing script, which is specif­i­cal­ly tai­lored to SVG files gen­er­at­ed by Potrace and may not work with every SVG file:

#!/bin/zsh
# Check if input is provided via a pipe
if [ -t 0 ]; then
    echo "No file path provided through the pipe."
    exit 1
fi
# Read the file path from the standard input (pipe)
read -r input_file
# Check if the file exists and is an SVG file
if [ ! -f "$input_file" ] || [[ "$input_file" != *.svg ]]; then
    echo "Invalid or non-SVG file provided: $input_file"
    exit 1
fi
# Create the output file path with the "_weiss" suffix
output_file="${input_file%.svg}_weiss.svg"
# Insert <rect> tag before <metadata> and save to new file
sed '/<metadata>/i\
<rect width="100%" height="100%" fill="white"/>' "$input_file" > "$output_file"
# Output the new file path
echo "$output_file"

Like all oth­er scripts, this one is saved in the fold­er $HOME/Applications as add_white_background. The cor­re­spond­ing invo­ca­tion can then look some­thing like this:

echo "/path/to/image.png" | potrace | add_white_background

While the Auto­trace solu­tion can han­dle col­ors to a cer­tain extent, the result is not as close to the orig­i­nal, and the cre­at­ed paths are essen­tial­ly just path frag­ments. How­ev­er, it may suf­fice to quick­ly gen­er­ate a rea­son­ably sim­i­lar vec­tor graph­ic for scal­ing images. Addi­tion­al­ly, it is pos­si­ble that bet­ter results can be achieved through improved set­tings in the options. I would be grate­ful for any tips.

The complete Call

Now all the com­po­nents are com­bined, and a logo can be cre­at­ed, for instance, for a blog about Obsid­i­an.

echo "Create a logo for a blog that discusses the PKM tool Obsidian" | fabric -sp create_mylogo | CreateLogo | svgPot | add_white_background

With this invo­ca­tion, the fol­low­ing image was cre­at­ed, which cap­tures the theme quite well:

The image features a stylized representation of an open book, with abstract shapes resembling branches or a tree emerging from its center. The design incorporates circular nodes and lines, suggesting themes of knowledge, growth, or connectivity. The overall aesthetic is modern and digital, likely symbolizing the intersection of literature and technology or the growth of information.

As well as the cor­re­spond­ing SVG:

Converted Image: The image features a stylized representation of an open book, with abstract shapes resembling branches or a tree emerging from its center. The design incorporates circular nodes and lines, suggesting themes of knowledge, growth, or connectivity. The overall aesthetic is modern and digital, likely symbolizing the intersection of literature and technology or the growth of information.

If the Auto­trace script is used instead of the Potrace script, the SVG file for the same PNG appears as fol­lows. Here, adjust­ments to the thresh­old would be nec­es­sary to achieve a bet­ter result. Note: Be sure to dis­able dark mode here as well! The script for set­ting the white back­ground would need to be adjust­ed for the SVGs gen­er­at­ed by Auto­trace.

Converted Image: The image features a stylized representation of an open book, with abstract shapes resembling branches or a tree emerging from its center. The design incorporates circular nodes and lines, suggesting themes of knowledge, growth, or connectivity. The overall aesthetic is modern and digital, likely symbolizing the intersection of literature and technology or the growth of information.

Conclusion

DALL‑E, Auto­trace, and Potrace pro­vide an effi­cient means of quick­ly gen­er­at­ing vec­tor graph­ics. As I men­tioned in my con­clu­sion in the arti­cle Fast and Easy Image Gen­er­a­tion with Fab­ric and Ope­nAI, while these work­flows are indeed help­ful, they are pri­mar­i­ly intend­ed a source of inspi­ra­tion and start­ing points for your own ideas.

This arti­cle also aims to demon­strate how pow­er­ful and flex­i­ble the com­bi­na­tion of var­i­ous tools with Fab­ric can be, offer­ing a sol­id foun­da­tion for fur­ther automa­tion and opti­miza­tion of graph­ics process­es.

I hope to achieve these two goals. The com­ment sec­tion is open for ideas, feed­back, praise, or what­ev­er else you may wish to share.

2 responses to “Efficient Logo Generation with Fabric, DALL‑E, and Vectorization Tools”

  1. @leif unfor­tu­nate­ly I have yet to find a very good open source trac­ing tool. I’d often gen­er­ate images with AI and then recre­ate them in inkscape man­u­al­ly as it’s real­ly not that hard if you’re famil­iar with basic inkscape.

    Alter­na­tive­ly inkscape has some real­ly good trac­ing if you have time to mess around with all of it’s options. I used bright­ness cut­off trac­er and got bet­ter results than what you had in the arti­cle. That being said auto traced SVG need to be fixed man­u­al­ly either way.

    1. Thanks for your com­ment! There is def­i­nite­ly a need for deep­er inves­ti­ga­tion into the var­i­ous options, and you’re right—manual adjust­ments are required in the end. Nev­er­the­less, I was impressed with how well Potrace works, espe­cial­ly for sim­ple, min­i­mal­is­tic black-and-white logos straight out of the box. As I men­tioned, this lit­tle exam­ple is more of an inspi­ra­tional nudge to show what’s pos­si­ble using the com­mand line with some text, Fab­ric, the right pat­tern, and addi­tion­al tools like a shell script and Potrace. I’ll def­i­nite­ly look into the options fur­ther!

Leave a Reply

Your email address will not be published. Required fields are marked *