Skip to content

Enhance Icon Generation: Optimize PNGs, Add WebP and SVG Outputs #39

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

SamiS0830
Copy link

@SamiS0830 SamiS0830 commented Jun 5, 2025

Thank you very much for reviewing, this is my first pull request! Please let me know if any adjustments are needed.

Fixes

Description

Enhances Icon Generation: 1) compresses PNGs 2) Produces a smaller, broadly supported file (WebP) 3) Adds SVG output

  1. Optimizes PNG generation: after writing each PNG, the script runs optipng -o7 to losslessly compress the file. Reduces average PNG size by roughly 50%.
  2. Adds WebP output: uses Pillow to open the newly generated PNG and save a WebP version at quality=85. Produces a smaller, broadly supported raster format alongside the existing PNG.
  3. Adds SVG output: adds a new function (create_svg_context()) to create a Cairo SVGSurface. Re-draws each icon onto the SVG canvas and calls (show_page()). Provides a resolution-independent vector version of every icon.
  4. Impact: Smaller PNGs reduce bandwidth, while adding WebP further cuts file size for modern browsers. SVG provides infinitely scalable format that never blurs, which is essential for high DPI displays and print materials.
  5. Dependencies: To build and test locally, you will need:
    a. OptiPNG installed in your path
    b. Pillow

Technical details

Requires OptiPNG installed in your path and Pillow

Tests

To verify this PR fixes the problem, run the script and confirm it generates PNG files that are roughly 50% smaller in size, alongside corresponding SVG and WebP files for each PNG. Check that all three formats open correctly without quality loss, and test with different inputs to ensure consistent output and no errors

Checklist

  • My pull request has a descriptive title (not a vague title like Update index.md).
  • My pull request targets the default branch of the repository (main or master).
  • My commit messages follow best practices.
  • My code follows the established code style of the repository.
  • I added or updated tests for the changes I made (if applicable).
  • I added or updated documentation (if applicable).
  • I tried running the project locally and verified that there are no
    visible errors.
    • (I was unable to run the project locally as I made my edits using GitHub’s “Fork this repository and edit” feature.)

Developer Certificate of Origin

For the purposes of this DCO, "license" is equivalent to "license or public domain dedication," and "open source license" is equivalent to "open content license or public domain dedication."

Developer Certificate of Origin
Developer Certificate of Origin
Version 1.1

Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
1 Letterman Drive
Suite D4700
San Francisco, CA, 94129

Everyone is permitted to copy and distribute verbatim copies of this
license document, but changing it is not allowed.


Developer's Certificate of Origin 1.1

By making a contribution to this project, I certify that:

(a) The contribution was created in whole or in part by me and I
    have the right to submit it under the open source license
    indicated in the file; or

(b) The contribution is based upon previous work that, to the best
    of my knowledge, is covered under an appropriate open source
    license and I have the right under that license to submit that
    work with modifications, whether created in whole or in part
    by me, under the same open source license (unless I am
    permitted to submit under a different license), as indicated
    in the file; or

(c) The contribution was provided directly to me by some other
    person who certified (a), (b) or (c) and I have not modified
    it.

(d) I understand and agree that this project and the contribution
    are public and that a record of the contribution (including all
    personal information I submit with it, including my sign-off) is
    maintained indefinitely and may be redistributed consistent with
    this project or the open source license(s) involved.
1.
 Optimizes PNG generation: after writing each PNG, the script runs OptiPNG -o7 to losslessly compress the file. Reduces average PNG size by roughly 50% 
2. 
Adds WebP output: uses Pillow to open the newly generated PNG and save a WebP version at quality=85. Produces a smaller, broadly supported raster format alongside the existing PNG
3. 
Adds SVG output: adds a new function (create_svg_context()) to create a Cairo SVGSurface. Re-draws each icon onto the SVG canvas and calls show_page(). Provides a resolution-independent vector version of every icon.

4. Impact: Smaller PNGs reduce bandwidth, while adding WebP further cuts file size for modern browsers. SVG provides infinitely scalable format that never blurs, which is essential for high DPI displays and print materials
5. Dependencies: To build and test locally, you will need: 
      a. OptiPNG installed in your path
      b. Pillow 

Thank you very much for reviewing, this is my first pull request! Please let me know if any adjustments are needed.
@SamiS0830 SamiS0830 requested a review from a team as a code owner June 5, 2025 05:27
@SamiS0830 SamiS0830 requested review from TimidRobot and possumbilities and removed request for a team June 5, 2025 05:27
@SamiS0830 SamiS0830 closed this Jun 5, 2025
@SamiS0830 SamiS0830 reopened this Jun 5, 2025
@cc-open-source-bot cc-open-source-bot moved this to In review in TimidRobot Jun 5, 2025
@TimidRobot TimidRobot self-assigned this Jun 5, 2025
@TimidRobot
Copy link
Member

@SamiS0830 thank you for this pull request (PR)!

I haven't touched this code base in quite a while, so I expect it will take me a week or two to review this PR.

@SamiS0830

This comment was marked as duplicate.

@SamiS0830 SamiS0830 closed this Jun 7, 2025
@github-project-automation github-project-automation bot moved this from In review to Done in TimidRobot Jun 7, 2025
@SamiS0830 SamiS0830 reopened this Jun 7, 2025
@SamiS0830
Copy link
Author

@SamiS0830 thank you for this pull request (PR)!

I haven't touched this code base in quite a while, so I expect it will take me a week or two to review this PR.

Thank you very much, I really appreciate it!

@TimidRobot TimidRobot moved this from Done to In review in TimidRobot Jun 10, 2025
Copy link
Member

@TimidRobot TimidRobot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great work. With an optimization level of 2 and the WebP and SVG files removed this results in:

  • ~16% reduction in total size (127M ➡️ 107M)
  • only a modest increase in script duration (14 sec ➡️ 2 min 59 sec)
@@ -195,6 +202,22 @@ def main():
# Will raise and exception on error
ctx.get_target().write_to_png(filepath)

# Optimize the just‐saved PNG with optipng (lossless compression)
os.system(f"optipng -o7 {filepath}")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please quiet the output and set optimization level to 2:

os.system(f"optipng -o2 -quiet {filepath}")

File size comparison in bytes:

File prefix Prev o1 o2 o3 o5 o7
www/i/l/by-sa/000000/ff/ff/ff/76x22 1105 582 553 553 553 553
www/i/l/by-sa/000000/ff/ff/ff/88x31 17096 871 829 829 829 824

Script duration in seconds

Prev o1 o2 o3 o5 o7
14 132 179 240 434 1130
@@ -135,6 +136,12 @@ def genicon(
show_chars(ctx, characters, foreground, padding, width, height)
return ctx

#function to create a Cairo canvas that write to a SVG file
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a space after the hash and capitalize "function"

Comment on lines +208 to +219
# Convert PNG -> WebP (smaller file size, quality=85)
img = Image.open(filepath)
webp_filepath = filepath.replace(".png", ".webp")
img.save(webp_filepath, format="webp", quality=85)

# Also render the same icon as SVG
svg_filepath = filepath.replace(".png", ".svg")
svg_ctx = create_svg_context(width, height, svg_filepath)
set_background(svg_ctx, background, width, height)
configure_font(svg_ctx, font_size)
show_chars(svg_ctx, chars, foreground, padding, width, height)
svg_ctx.show_page()
Copy link
Member

@TimidRobot TimidRobot Jul 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove WebP and SVG output. Both result in larger files than PNG.

File type size comparison in bytes:

File prefix PNG SVG scour WebP
www/i/l/by-sa/000000/ff/ff/ff/76x22 553 4471 2854 588
www/i/l/by-sa/000000/ff/ff/ff/88x31 829 4531 2813 858

The "scour" column represents SVGs updated using scour-project/scour: Scour - An SVG Optimizer / Cleaner

python3-gi-cairo \
python3-pil \
Copy link
Member

@TimidRobot TimidRobot Jul 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove python3-pil WebP dependency (see comment on lines +208 to +219 for rationale)

@@ -4,6 +4,7 @@
# Standard library
from functools import reduce
from itertools import product
from PIL import Image
Copy link
Member

@TimidRobot TimidRobot Jul 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove WebP related import (see comment on lines +208 to +219 for rationale)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
2 participants