svgcleaner could help you to clean up your SVG files from the unnecessary data.

Last update: May 19, 2022

svgcleaner build status

svgcleaner helps you clean up your SVG files, keeping them free from unnecessary data.


Purpose

The main purpose of svgcleaner is to losslessly reduce the size of an SVG image, created in a vector editing application, before publishing.

Usually more than half of an SVG image's data is useless for rendering. For example:

  • Temporary data used by the vector editing application
  • Non-optimal SVG structure representation
  • Unused and invisible graphical elements

... Are all unnecessary in a published SVG.

Goals

  1. Correctness - svgcleaner should not break an SVG file
  2. Cleaning ratio - Higher is better
  3. Performance - An average SVG file processing time should be closer to ~1ms on a modern PC

Alternatives

In addition to the main advantages of svgcleaner — like correctness, cleaning ratio and performance, which are described below — there are some more nuances to be aware of:

  1. svgcleaner cleans only one SVG file. It doesn't process SVGZ files. It doesn't process directories. It doesn't do anything else. Just one task*.
  2. svgcleaner is strictly lossless by default. There are no destructive cleaning options enabled by default.
  3. svgcleaner is portable. You can build it into a single executable without any external dependencies.

* You can get all of these features using the GUI.

Charts

See Testing notes for details.

All stats were collected using the latest release version.

Correctness

Less is better.

Cleaning ratio

More is better.

* scour creates bigger files (-18.78%).

Cleaning time

Less is better.

Other

Collection Size Before (MiB) Size After (MiB) Ratio (%)
Breeze icons theme 21.72 11.09 48.91
Ardis icons theme 11.82 5.23 55.74
Humanity icons theme 8.56 3.08 64.01
Open Icon Library 207.45 69.44 66.53
Elementary icons theme 17.72 7.09 59.95
Adwaita icons theme 2.21 0.37 83.08
Faience icon theme 22.35 11.14 50.16
GCP Icons 0.344 0.082 75.9

Documentation

Documentation can be found here.

Limitations

svgcleaner shouldn't change your file unless you tell it to, but there are still things that can't be preserved. So even if you disable all cleaning options there are still things that will be changed, such as:

  • Original indent is not preserved
  • All colors will be formatted as #RRGGBB and #RGB
  • DOCTYPE, CDATA will be processed and removed
  • CSS support is minimal
  • CSS from the style element will be extracted and processes. The style element will be removed.
  • The style attribute will be split into attributes
  • The class attribute will be processed and removed
  • Paths and transformations will be reformatted
  • currentColor and inherit attributes values will be resolved
  • Referenced elements will be moved to the defs element
  • IRI and FuncIRI attributes that reference non-existing objects will be removed
  • If the offset attribute value of the stop element is represented as percentage - it will be converted into a decimal number

Usage

CLI

svgcleaner in.svg out.svg

Change default options:

svgcleaner --indent=2 --paths-coordinates-precision=5 --join-arcto-flags=yes in.svg out.svg

Use --help for a list of the cleaning options and see the documentation for more details.

GUI

You can get a GUI here.

Downloads

You can get prebuilt packages here.

Building

Dependency: Rust

cargo build --release

If you're a Rust programmer, you can install svgcleaner using:

cargo install svgcleaner

Contributing and Issues

See CONTRIBUTING.md for details.

FAQ

See FAQ.md for details.

License

svgcleaner is licensed under the GPL-2.0.

GitHub

https://github.com/RazrFalcon/svgcleaner
Comments
  • 1. prebuilt issue

    I clicked on prebuilt package and it is linked to GUI release.i wanted to install in centos so svgcleaner release package https://github.com/RazrFalcon/svgcleaner/archive/v0.9.1.tar.gz is sufficient or i have to install rust first ??

    Reviewed by bydbest at 2017-11-22 18:37
  • 2. Ubuntu 16.04 PPA fails to fetch

    Won't install on Ubuntu 16.04 via PPA:

    E: Failed to fetch http://ppa.launchpad.net/svg-cleaner-team/svgcleaner/ubuntu/dists/xenial/main/binary-i386/Packages 404 Not Found

    E: Unable to locate package svg-cleaner

    Reviewed by ghost at 2016-04-23 23:55
  • 3. Doesn't compile

    tried trunk and v0.6.2 on Gentoo, GCC 4.9.2. Qt 4.8.6. Fails in both cases with

    wizarddialog.cpp: In member function ‘void WizardDialog::onRadioSelected()’:
    wizarddialog.cpp:299:59: error: ‘class QRadioButton’ has no member named ‘accessibleName’
         settings.setValue(SettingKey::Wizard::SaveMode, rBtn->accessibleName());
                                                               ^
    wizarddialog.cpp: In member function ‘QString WizardDialog::findLabel(const QString&)’:
    wizarddialog.cpp:549:22: error: ‘class QLabel’ has no member named ‘accessibleName’
                 if (lbl->accessibleName() == accessibleName)
                          ^
    
    Reviewed by petamem at 2015-04-20 15:16
  • 4. The indent of content of text tag should not be changed

    if indenting is set to anything except "none", then text in text tag will be rendered as text with indent, that could even move it outside of viewbox. <?xml version="1.0" encoding="UTF-8" standalone="no"?> <svg xmlns="http://www.w3.org/2000/svg" version="1.1" x="0px" y="0px" viewBox="0 0 34.06945 33.11168" enable-background="new 0 0 34.06945 33.11168" xml:space="preserve" id="svg2"> <defs id="defs30"/> <text y="21.539351" x="5.6560216" style="font-size:18.9988308px;font-family:NotoSans" id="text13" font-size="18.99883px">IP</text> </svg>

    For text tag the content should never change, so it should be somehow excluded from indenting.

    Reviewed by Vasilich at 2017-05-29 10:00
  • 5. removes attributes of svg2.0-Elements (meshgradient)

    Prozessing File:Radar_Mac.svg with svgcleaner leads to a removement of the SVG 2.0-Element meshgradient.

    $ svgcleaner input.svg.txt output.svg.txt --allow-bigger-file --indent 1 --remove-nonsvg-attributes no --remove-nonsvg-elements no --remove-unused-defs no --remove-declarations no --remove-unreferenced-ids no

    Warning: Could not resolve the 'fill' IRI reference: a. Fallback to 'none'.

    This seems to be related to #126 .

    Input

    Input.svg.txt

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE svg  PUBLIC '-//W3C//DTD SVG 1.1//EN'  'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>
    <svg height="80" viewBox="0 0 21.167 21.167" width="80" xmlns="http://www.w3.org/2000/svg">
     <defs>
      <meshgradient id="a" x="61.856" y="379.399" gradientTransform="rotate(-45 -414.2 244.26)" gradientUnits="userSpaceOnUse">
       <meshrow>
        <meshpatch>
         <stop path="c 0,5.77195 -4.67909,10.451 -10.451,10.451" stop-color="#1c0000"/>
         <stop path="l 0,-10.451"/>
         <stop path="l 0,0"/>
         <stop path="l 10.451,0"/>
        </meshpatch>
        <meshpatch>
         <stop path="c -5.77195,0 -10.451,-4.67909 -10.451,-10.451"/>
         <stop path="l 10.451,0"/>
         <stop path="l 0,0"/>
        </meshpatch>
        <meshpatch>
         <stop path="c 0,-5.77195 4.67909,-10.451 10.451,-10.451"/>
         <stop path="l -4.21753e-005,10.451" stop-color="#3e6915"/>
         <stop path="l 4.21753e-005,0" stop-color="#3e6915"/>
        </meshpatch>
        <meshpatch>
         <stop path="c 5.77195,0 10.4511,4.67916 10.451,10.451"/>
         <stop path="l -10.451,-7.35946e-006" stop-color="#7dd32a"/>
         <stop path="l -1.29023e-005,3.08016e-006" stop-color="#7dd32a"/>
        </meshpatch>
       </meshrow>
      </meshgradient>
     </defs>
     <path d="m10.736.133a10.451 10.451 0 0 0 -7.543 3.06 10.451 10.451 0 0 0 0 14.78 10.451 10.451 0 0 0 14.78 0 10.451 10.451 0 0 0 0-14.78 10.451 10.451 0 0 0 -7.237-3.06z" fill="url(#a)" stroke="#7dd32a" stroke-linecap="round" stroke-linejoin="round" stroke-width=".265" paint-order="normal"/>
    </svg>
    
    

    input

    Output

    Output.svg.txt

    <?xml version="1.0" encoding="UTF-8"?>
    <svg height="80" viewBox="0 0 21.167 21.167" width="80" xmlns="http://www.w3.org/2000/svg">
     <defs>
      <meshgradient>
       <meshrow>
        <meshpatch>
         <stop path="c 0,5.77195 -4.67909,10.451 -10.451,10.451" stop-color="#1c0000"/>
         <stop path="l 0,-10.451"/>
         <stop path="l 0,0"/>
         <stop path="l 10.451,0"/>
        </meshpatch>
        <meshpatch>
         <stop path="c -5.77195,0 -10.451,-4.67909 -10.451,-10.451"/>
         <stop path="l 10.451,0"/>
         <stop path="l 0,0"/>
        </meshpatch>
        <meshpatch>
         <stop path="c 0,-5.77195 4.67909,-10.451 10.451,-10.451"/>
         <stop path="l -4.21753e-005,10.451" stop-color="#3e6915"/>
         <stop path="l 4.21753e-005,0" stop-color="#3e6915"/>
        </meshpatch>
        <meshpatch>
         <stop path="c 5.77195,0 10.4511,4.67916 10.451,10.451"/>
         <stop path="l -10.451,-7.35946e-006" stop-color="#7dd32a"/>
         <stop path="l -1.29023e-005,3.08016e-006" stop-color="#7dd32a"/>
        </meshpatch>
       </meshrow>
      </meshgradient>
     </defs>
     <path d="m10.736.133a10.451 10.451 0 0 0 -7.543 3.06 10.451 10.451 0 0 0 0 14.78 10.451 10.451 0 0 0 14.78 0 10.451 10.451 0 0 0 0-14.78 10.451 10.451 0 0 0 -7.237-3.06z" fill="none" stroke="#7dd32a" stroke-linecap="round" stroke-linejoin="round" stroke-width=".265" paint-order="normal"/>
    </svg>
    

    output


    Copyright

    Iicense: LGPL

    Author: Habitator terrae

    source: https://commons.wikimedia.org/wiki/File:Radar_Mac.svg

    Reviewed by JoKalliauer at 2018-11-01 12:09
  • 6. Group by style may produce ungroupable groups

    As the title suggests, in some cases the --group-by-style option may produce groups that should be ungrouped by svgcleaner (40cc1b7).

    Input

    <svg height="50" width="50"  viewBox="0 0 50 50" xmlns="http://www.w3.org/2000/svg">
      <ellipse cx="25" cy="25" rx="10" ry="10" style="fill:#000000" />
      <ellipse cx="25" cy="25" rx="10" ry="10" style="fill:#000000" />
      <ellipse cx="25" cy="25" rx="10" ry="10" style="fill:#000000" />
    </svg>
    

    Output

    • svgcleaner --indent 2 --group-by-style true <files>
    • svgcleaner --indent 2 --group-by-style true --multipass true <files>
    <svg height="50" viewBox="0 0 50 50" width="50" xmlns="http://www.w3.org/2000/svg">
      <g>
        <ellipse cx="25" cy="25" rx="10" ry="10"/>
        <ellipse cx="25" cy="25" rx="10" ry="10"/>
        <ellipse cx="25" cy="25" rx="10" ry="10"/>
      </g>
    </svg>
    
    • svgcleaner --indent 2 --group-by-style false <files>
    <svg height="50" viewBox="0 0 50 50" width="50" xmlns="http://www.w3.org/2000/svg">
      <ellipse cx="25" cy="25" rx="10" ry="10"/>
      <ellipse cx="25" cy="25" rx="10" ry="10"/>
      <ellipse cx="25" cy="25" rx="10" ry="10"/>
    </svg>
    

    One should expect --multipass true to fix this, but it keeps the group untouched.

    Reviewed by slyrz at 2017-01-17 13:00
  • 7. Breaking SVG with fill=none, mask and fill-rule

    Given the input SVG (I simplified it as much as i could to preserve the problem) rounded-red.svg:

    <svg viewBox="0 0 30 20"
        xmlns="http://www.w3.org/2000/svg" 
        xmlns:xlink="http://www.w3.org/1999/xlink">
        <defs>
            <rect id="a" height="20" rx="5" width="30"/>
        </defs>
        <g fill="none" fill-rule="evenodd">
            <mask id="b" fill="#fff">
                <use xlink:href="#a"/>
            </mask>
            <g fill="red" mask="url(#b)">
                <path d="M0 0h30v20H0z"/>
            </g>
        </g>
    </svg>
    

    and passing it to svgcleaner 0.9.4:

    $ ./svgcleaner -V
    svgcleaner 0.9.4
    $ ./svgcleaner rounded-red.svg broken.svg
    Your image is 35.17% smaller now.
    

    generates broken.svg with content:

    <svg viewBox="0 0 30 20" 
        xmlns="http://www.w3.org/2000/svg" 
        xmlns:xlink="http://www.w3.org/1999/xlink">
        <mask id="a" fill="#fff">
            <rect fill="none" height="20" rx="5" width="30"/>
        </mask>
        <g fill="#f00" fill-rule="evenodd" mask="url(#a)">
            <path d="m0 0h30v20h-30z"/>
        </g>
    </svg>
    

    (xml formatted for clarity)

    Images render vastly different (left original, right optimised): image

    Screenshot from Chrome, same in Firefox, rendered via HTML snippet:

    <img src="rounded-red.svg" width="200" height="200" style="border: 1px solid blue" />  
    <img src="broken.svg" width="200" height="200" style="border: 1px solid blue" />  
    
    Reviewed by stefanb at 2018-04-06 13:09
  • 8. stroke-dasharray : comma - space

    Reviewed by JoKalliauer at 2017-12-16 20:07
  • 9. Fix compilation with Qt 5.

    I was getting:

    main.cpp: In function 'int main(int, char**)': main.cpp:381:46: error: 'qInstallMsgHandler' was not declared in this scope

    qInstallMsgHandler() was deprecated and replaced with qInstallMessageHandler().

    Reviewed by mitchcurtis at 2014-12-09 15:36
  • 10. Prozessing files bigger than 10MB lead to: thread 'main' has overflowed its stack

    Processing a file above 10MB with following comand:

    $ svgcleaner Stations_Vélhop.svg output.svg

    lead to an error: thread 'main' has overflowed its stack

    Reviewed by JoKalliauer at 2017-12-25 19:54
  • 11. Remove overflow property where it has no effect

    Right now svgcleaner keeps overflow properties in the SVG files untouched. They can be removed for all elements that don't establish new viewports.

    Scour removes the overflow-property like this. The first if-case is probably the most effective one. At least I have SVGs where Inkscape added unnecessary overflow:visible styles to all my path elements.

    Reviewed by slyrz at 2017-01-21 10:09
  • 12. fill="rgba(0,0,0,255)" from usvg as Error: invalid color

    I processed a file with (usvg)[https://github.com/RazrFalcon/resvg/tree/master/usvg] and the result was fill="rgba(0,0,0,255)" however this "micro"-SVG is not accepted by svgcleaner.

    A mirco-SVG should be understood by everyone. If svgcleaner does not understand it is is either not a good choice for micro-SVG or it is a svgcleaner-bug.

    Example.svg

    Reviewed by JoKalliauer at 2021-10-30 11:59
  • 13. Invalid Attribute value at 216:50

    What should I check in my SVG File?

    15145-A0002ToSVG-result.zip

    maybe fill-rule="winding" ?

    And this token is not supported by the cleaner ?

    immagine

    Thank you.

    Reviewed by merco at 2021-10-13 16:23
  • 14. svgcleaner outputs `style=""`

    After just switching to svgcleaner from svgo, I noticed that svgcleaner outputs style="", which I presume is not strictly required. Wouldn't it make sense to remove this?

    Reviewed by jhpratt at 2021-08-15 07:41
  • 15. The comma disappeared after svgcleaner-gui

    Input

    <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 311.81 453.54">
      <text>
        <tspan class="cls-30" x="26.39" y="52">永</tspan>
        <tspan class="cls-31" x="40.02" y="52">,</tspan>
        <tspan x="49.19" y="52">远</tspan>
      </text>
    </svg>
    

    output

    <svg viewBox="0 0 311.81 453.54" xmlns="http://www.w3.org/2000/svg">
      <text>
        <tspan x="26.39" y="52">永</tspan>
        <tspan x="40.02" y="52" />
        <tspan x="49.19" y="52">远</tspan>
      </text>
    </svg>
    
    Reviewed by yisibl at 2021-08-05 03:28
  • 16. Inconsistent result with data

    Hi,

    Thanks for the wonderful library. I am facing a weird issue, it works sometimes and throws errors if I try another time.

    i:  SLM:000000007	
    Your image is 68.92% smaller now.**
    i:  SLM:000000035	
    Your image is 67.89% smaller now.
    

    When I run the same script again, it fails to process

    i:  SLM:000000007	
    Error: invalid attribute value at 277:56.
    i:  SLM:000000035	
    Your image is 67.87% smaller now.
    

    Any ideas on how to fix it?

    Reviewed by muthuvenkat at 2021-08-03 12:47
Related tags
A high-performance SVG renderer, powered by Rust based resvg and napi-rs.
A high-performance SVG renderer, powered by Rust based resvg and napi-rs.

resvg-js resvg-js is a high-performance SVG renderer, powered by Rust based resvg and napi-rs. Fast, safe and zero dependencies! No need for node-gyp

May 27, 2022
A cargo subcommand for creating GraphViz DOT files and dependency graphs
A cargo subcommand for creating GraphViz DOT files and dependency graphs

cargo-graph Linux: A cargo subcommand for building GraphViz DOT files of dependency graphs. This subcommand was originally based off and inspired by t

Apr 3, 2022
Graph data structure library for Rust.

petgraph Graph data structure library. Supports Rust 1.41 and later. Please read the API documentation here Crate feature flags: graphmap (default) en

May 20, 2022
picom-xrdesktop-companion is a program that runs alongside picom, that mirrors your desktop windows to the VR/XR space.
picom-xrdesktop-companion is a program that runs alongside picom, that mirrors your desktop windows to the VR/XR space.

picom-xrdesktop-companion picom-xrdesktop-companion What is this How to use Installation Dependencies Building Limitations Bugs Window stacking Questi

May 11, 2022
Czkawka is a simple, fast and easy to use app to remove unnecessary files from your computer.
Czkawka is a simple, fast and easy to use app to remove unnecessary files from your computer.

Multi functional app to find duplicates, empty folders, similar images etc.

May 25, 2022
Unwrap Macros to help Clean up code and improve production.

unwrap_helpers Unwrap Macros to help Clean up code and improve production. This does include a pub use of https://github.com/Mrp1Dev/loop_unwrap to ga

Nov 1, 2021
Cyg will help you to secure files in your repository directly using PGP encryption

cyg: Secure files in your repository Cyg will help you to secure files in your repository directly using PGP encryption. The name "cyg" was inspired b

May 7, 2022
Automatically check for SPF misconfigurations that could result in email spoofing

SPFJack Email spoofing is dead, but misconfiguration never dies. Purpose This project is designed to take in domain names and review their SPF records

Mar 27, 2022
This is a smart contract running on NEAR Protocol. It could be used to run a token sale.

Token Sale This is a smart contract running on NEAR Protocol. It could be used to run a token sale. Sale rules There are 2 periods: Sale and Grace. In

Dec 5, 2021
lemmy-help is a emmylua parser as well as a CLI which takes that parsed tree and converts it into vim help docs.
lemmy-help is a emmylua parser as well as a CLI which takes that parsed tree and converts it into vim help docs.

lemmy-help is a emmylua parser as well as a CLI which takes that parsed tree and converts it into vim help docs.

May 25, 2022
Clean up the lines of files in your code repository

lineman Clean up the lines of files in your code repository NOTE: While lineman does have tests in place to ensure it operates in a specific way, I st

Nov 25, 2021
A CLI tool which can help you automatically kill process of your choice. Useful for freeing up memory and CPU usage!
A CLI tool which can help you automatically kill process of your choice. Useful for freeing up memory and CPU usage!

Quickiller There are always programs such as chrome that keep eating up your resources even when closed! The only way to prevent this is to kill all o

Dec 8, 2021
A library to help you sew up your Ethereum project with Rust and just like develop in a common backend

SewUp Secondstate EWasm Utility Program, a library helps you sew up your Ethereum project with Rust and just like development in a common backend. The

May 24, 2022
laydown is a simple CLI application to help you prepare for your next Daily Standup

laydown is a simple CLI application to help you prepare for your next Daily Standup. No longer shall your name be called on only for you to stare into the abyss while you struggle to remember what you did yesterday.

May 6, 2022
Convert UFO .glif files to SVG, whether they're part of a font or not

Convert UFO glyph files (.glif) to SVG There exists already an svg2glif, but for some reason not the opposite operation. My MFEKglif editor treats .gl

Apr 26, 2022
Turns lines of text into SVG files.

Sentences 2 svg Does what it says on the tin. This takes in a file with some sentences and outputs numbered svgs. There are 3 arguments to keep in min

Jan 1, 2022
Convert your ascii diagram scribbles into happy little SVG

Svgbob Svgbob can create a nice graphical representation of your text diagrams. Svgbob provides a cli which takes text as an input and creates an svg

May 25, 2022
"putzen" is German and means cleaning. It helps keeping your disk clean of build and dependency artifacts safely.

Putzen "putzen" is German and means cleaning. It helps keeping your disk clean of build and dependency artifacts safely. About In short, putzen solves

Jan 31, 2022
nats-spy is a terminal tool to help you to monitor NATS messages.

nats-spy nats-spy is a terminal tool to help you to monitor NATS messages. Install Homebrew (macOS) brew install alihanyalcin/nats-spy/nats-spy Usage

May 24, 2022
Telegram bot help you to run Rust code in Telegram via Rust playground
Telegram bot help you to run Rust code in Telegram via Rust playground

RPG_BOT (Rust Playground Bot) Telegram bot help you to run Rust code in Telegram via Rust playground Bot interface The bot supports 3 straightforward

Mar 9, 2022