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.
Install Python 3.10 or higher, just drop into dos and type the follow to confirm/install Python
python
Install GTK3 Runtime:
Download from: GTK3-Runtime-3.24.31-2022-01-04-ts-win64.exe
Run installer with default options
Install dependencies
pip install cairosvg pillow requests
Save this file as
go.py
in a new folderimport 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
Shared Components > Static Application Files > Create File
Select the
app_icons.zip
fileClick Create
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.