Convert Font APEX Icons to Application Icon sets

Convert Font APEX Icons to Application Icon sets

When you select an Application icon you get a choice of 32 icons and 8 colours.

When you pick an Icon, APEX bakes the colour into the Icon and saves it as 5 png images with various sizing and rounding.

It saves them in your Static Application files

APEX components, e.g the Breadcrumb, represent these on screen…

…by accessing the URL directly. For example, the login page & breadcrumb uses the 512 icon.

However, do you ever find that the selection of 32 icons and 8 colours is not the icon/colour combination that you need?

Wouldn’t it be great to use any Font APEX / Colour / Rotation / Zoom combination?

Well, you can use the Upload your Own Icon by selecting anything from the Font APEX Github but I’m talking about more image customization

The Font APEX to App Icon Converter

I’ve created a Python script to convert Font APEX SVG icons into Oracle APEX application icons. The code generates all required icon sizes for APEX applications while supporting custom colors, rotation, positioning, and scaling.

This script converts Font APEX icons into the specific dimensions required for APEX applications:

  • Favicon (32x32)

  • Small rounded icon (144x144)

  • Small icon (192x192)

  • Large rounded icon (256x256)

  • Large icon (512x512)

These dimensions match the requirements specified in Oracle APEXs Application Icon settings. Here are some examples:

What it does?

  • Convert any Font APEX SVG to APEX application icons

  • Customize icon colors using hex codes or text

  • Support for transparent backgrounds

  • Adjust icon position for better centering

  • Rotate icons to any angle

  • Scale icons up or down

  • Automatically generates rounded corners where needed

  • Creates a zip file ready for APEX upload

Prerequisites

Apologies, this is Windows only script at this point.

  1. Install Python 3.10 or higher, just drop into dos and type the follow to confirm/install Python

     python
    
  2. Install GTK3 Runtime:

  3. Install dependencies

     pip install cairosvg pillow requests
    
  4. Save this file as go.py in a new folder

     import sys
     import os
     import requests
     from PIL import Image
     from io import BytesIO
     import re
     from zipfile import ZipFile
    
     # Initialize GTK path
     gtkbin = r'C:\Program Files\GTK3-Runtime Win64\bin'
     add_dll_dir = getattr(os, 'add_dll_directory', None)
     if callable(add_dll_dir):
         add_dll_dir(gtkbin)
     else:
         os.environ['PATH'] = os.pathsep.join((gtkbin, os.environ['PATH']))
    
     from cairosvg import svg2png
    
     def create_output_folder(folder_name="icons"):
         if not os.path.exists(folder_name):
             os.makedirs(folder_name)
         return folder_name
    
     def create_zip_archive(output_folder):
         zip_path = os.path.join(output_folder, 'app-icons.zip')
         with ZipFile(zip_path, 'w') as zip_file:
             for file in os.listdir(output_folder):
                 if file.endswith('.png'):
                     file_path = os.path.join(output_folder, file)
                     # Add files to the zip under the 'icons' folder
                     zip_file.write(file_path, os.path.join('icons', file))
         print(f"Created {zip_path}")
    
     def create_icons(svg_url, fg_color, bg_color, x_offset=0, y_offset=0, rotation_angle=0, zoom=1.0, output_folder="icons"):
         # Convert GitHub URL to raw content URL
         if "github.com" in svg_url:
             svg_url = svg_url.replace("github.com", "raw.githubusercontent.com")
             svg_url = svg_url.replace("/blob/", "/")
    
         # Download SVG content
         response = requests.get(svg_url)
         svg_content = response.text
    
         # Add fill attribute to the path element if it doesn't exist
         svg_content = svg_content.replace('<path d=', f'<path fill="{fg_color}" d=')
    
         # Replace colors in SVG
         svg_content = svg_content.replace('currentColor', fg_color)
    
         # Find viewBox dimensions and apply transforms
         match = re.search(r'<svg[^>]*viewBox="([^"]*)"', svg_content)
         if match:
             viewbox = match.group(1).split()
             min_x, min_y, width, height = map(float, viewbox)
    
             # Calculate center point of original image
             center_x = min_x + (width / 2)
             center_y = min_y + (height / 2)
    
             # First rotate around center, then scale from center, then translate
             transform = f'transform="rotate({rotation_angle} {center_x} {center_y}) translate({center_x} {center_y}) scale({zoom}) translate({-center_x + x_offset} {-center_y + y_offset})"'
             svg_content = re.sub(r'(<svg[^>]*>)(.*?)(</svg>)', f'\\1<g {transform}>\\2</g>\\3', svg_content, flags=re.DOTALL)
    
         # Define dimensions for different icons
         icons = {
             'favicon': (32, 32, False),
             'small-rounded': (144, 144, True),
             'small': (192, 192, False),
             'large-rounded': (256, 256, True),
             'large': (512, 512, False)
         }
    
         # Ensure output folder exists
         output_folder = create_output_folder(output_folder)
    
         for name, (width, height, rounded) in icons.items():
             # Convert SVG to PNG with background color
             png_data = svg2png(
                 bytestring=svg_content.encode('utf-8'),
                 background_color=bg_color,
                 output_width=width,
                 output_height=height
             )
    
             # If rounded corners are needed
             if rounded:
                 # Create rounded corners using PIL
                 img = Image.open(BytesIO(png_data))
                 mask = Image.new('L', (width, height), 0)
    
                 # Create circular mask
                 radius = width // 10
                 for x in range(width):
                     for y in range(height):
                         # Check if pixel should be visible in rounded corners
                         if (x < radius and y < radius and 
                             ((x - radius) ** 2 + (y - radius) ** 2) > radius ** 2):
                             continue
                         if (x < radius and y > height - radius and 
                             ((x - radius) ** 2 + (y - height + radius) ** 2) > radius ** 2):
                             continue
                         if (x > width - radius and y < radius and 
                             ((x - width + radius) ** 2 + (y - radius) ** 2) > radius ** 2):
                             continue
                         if (x > width - radius and y > height - radius and 
                             ((x - width + radius) ** 2 + (y - height + radius) ** 2) > radius ** 2):
                             continue
                         mask.putpixel((x, y), 255)
    
                 img.putalpha(mask)
                 output_path = os.path.join(output_folder, f'app-icon-{width}-rounded.png')
                 img.save(output_path, 'PNG')
                 print(f"Created {output_path}")
             else:
                 # Save regular icon
                 output_path = os.path.join(output_folder, f'app-icon-{width}.png')
                 with open(output_path, 'wb') as f:
                     f.write(png_data)
                 print(f"Created {output_path}")
    
         # Create zip archive of all generated icons
         create_zip_archive(output_folder)
    
     if __name__ == "__main__":
         if len(sys.argv) != 8:
             print("Usage: python go.py <svg_url> <fg_color> <bg_color> <x_offset> <y_offset> <rotation_angle> <zoom>")
             print("Example: python go.py https://github.com/oracle/font-apex/blob/master/svgs/small/space-shuttle.svg #000000 transparent 0 -0.5 45 1.2")
             sys.exit(1)
    
         svg_url = sys.argv[1]
         fg_color = sys.argv[2]
         bg_color = sys.argv[3]
         x_offset = float(sys.argv[4])
         y_offset = float(sys.argv[5])
         rotation_angle = float(sys.argv[6])
         zoom = float(sys.argv[7])
    
         print(f"Processing SVG from: {svg_url}")
         print(f"Foreground color: {fg_color}")
         print(f"Background color: {bg_color}")
         print(f"X offset: {x_offset}")
         print(f"Y offset: {y_offset}")
         print(f"Rotation angle: {rotation_angle} degrees")
         print(f"Zoom: {zoom}x")
    
         create_icons(svg_url, fg_color, bg_color, x_offset, y_offset, rotation_angle, zoom)
    

Usage

Usage

python go.py <svg_url> <fg_color> <bg_color> <x_offset> <y_offset> <rotation_angle> <zoom>

Example

Choose an icon here

python go.py "https://github.com/oracle/font-apex/blob/master/svgs/small/user-secret.svg" "#bd93f9" "#44475a" 0 0.5 0 0.7

Parameters

  • svg_url: URL to Font APEX SVG (from GitHub repository)

  • fg_color: Hex color code for icon (e.g., "#000000")

  • bg_color: Background color or "transparent"

  • x_offset: Horizontal position adjustment (-2 to 2)

  • y_offset: Vertical position adjustment (-2 to 2)

  • rotation_angle: Degrees to rotate icon (0-360)

  • zoom: Scale factor (1.0 = original size, 1.2 = 20% larger). 0.7 seems to work well

Examples

Standard icon

python go.py "https://github.com/oracle/font-apex/blob/master/svgs/small/apex.svg" 
"indigo" "yellow"  0 0.5 0 0.7

Rotated icon with slight vertical adjustment:

python go.py "https://github.com/oracle/font-apex/blob/master/svgs/small/rocket.svg" "pink" "brown" 0 -0.5 100 0.7

Output

The script creates an icons folder containing:

  • app-icon-32.png (favicon)

  • app-icon-144-rounded.png (small rounded)

  • app-icon-192.png (small)

  • app-icon-256-rounded.png (large rounded)

  • app-icon-512.png (large)

  • app-icons.zip (all icons in a zip file)

The generated zip file can be directly uploaded in APEX Application Icon settings.

Icon Installation

  1. Shared Components > Static Application Files > Create File

  2. Select the app_icons.zip file

  3. Click Create

  4. Enjoy!

Common Issues

If you get PATH warnings during installation, add Python Scripts to your system PATH:

textC:\Users\[username]\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\Scripts

Or use --no-warn-script-location when installing packages.

Limitations

  • Windows-only due to GTK3 Runtime dependency

  • Only works with Font APEX SVG files from the GitHub repository

  • Some icons may require position adjustment for perfect centering

ENJOY

What’s the picture? Its The Hell Hole near Gildersome and Churwell.