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

Related tags

Graphics svg rust cleaner
Overview

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.

Comments
  • prebuilt issue

    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 ??

    opened by bydbest 16
  • Ubuntu 16.04 PPA fails to fetch

    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

    opened by ghost 14
  • Doesn't compile

    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)
                          ^
    
    opened by petamem 12
  • The indent of content of text tag should not be changed

    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.

    opened by Vasilich 11
  • removes attributes of svg2.0-Elements (meshgradient)

    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

    opened by JoKalliauer 10
  • Group by style may produce ungroupable groups

    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.

    opened by slyrz 10
  • Breaking SVG with fill=none, mask and fill-rule

    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" />  
    
    Bug 
    opened by stefanb 9
  • stroke-dasharray : comma - space

    stroke-dasharray : comma - space

    opened by JoKalliauer 9
  • Fix compilation with Qt 5.

    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().

    opened by mitchcurtis 9
  • Prozessing files bigger than 10MB lead to: thread 'main' has overflowed its stack

    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

    Complex Bug 
    opened by JoKalliauer 8
  • Remove overflow property where it has no effect

    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.

    Improvement 
    opened by slyrz 8
  • fill=

    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

    opened by JoKalliauer 1
  • Invalid Attribute value at 216:50

    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.

    opened by merco 1
  • svgcleaner outputs `style=

    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?

    opened by jhpratt 6
  • The comma disappeared after svgcleaner-gui

    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>
    
    opened by yisibl 0
  • Inconsistent result with data

    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?

    opened by muthuvenkat 4
Releases(v0.9.5)
Owner
Evgeniy Reizner
Evgeniy Reizner
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

一丝 744 Jan 7, 2023
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

Kevin K. 213 Nov 24, 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

null 2k Jan 9, 2023
Compact, efficient data structures in contiguous byte arrays

Sokoban Compact, efficient data structures in contiguous byte arrays. Benchmarks Based on simple benchmarks, the naive performance of Sokoban data str

Ellipsis Labs 75 Jun 5, 2023
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

yshui 15 Dec 9, 2022
Level up your shader game with the GPU + Rust advantage!

Gravy (WIP) Ya know, my momma always said everything's better with Gravy... Gravy is a shader programming framework and toolkit built on the union of

Dr. Rubisco 8 Nov 7, 2023
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.

Rafał Mikrut 9.2k Jan 4, 2023
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

Ascending Creations 2 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

Hisam Fahri 2 Aug 31, 2022
envelope - a command line utility and tool to help you manage your .env files

envelope envelope is a command line utility and tool to help you manage your .env files. How it works envelope is basically a command line utility tha

Mattia Righetti 6 Oct 14, 2023
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

Joseph T. Lyons 4 Nov 25, 2021
Media Cleaner is a simple CLI tool to clean up your media library based on your Overseerr requests and Tautulli history, written in Rust.

Media Cleaner Media Cleaner is a simple CLI tool to clean up your media library based on your Overseerr requests and Tautulli history, written in Rust

Felix Bjerhem Aronsson 21 Mar 22, 2023
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

Alex (LunarCA) 2 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

Harry Nguyen 0 Dec 5, 2021
Finds imports that could be exploited, still requires manual analysis.

drv-vuln-scanner Vulnerable driver scanning tool for win64, put drivers to scan in drv/. Finds imports that could be exploited, still requires manual

selene 24 Dec 10, 2022
What if we could check declarative macros before using them?

expandable An opinionated attribute-macro based macro_rules! expansion checker. Textbook example rustc treats macro definitions as some opaque piece o

Sasha Pourcelot 13 Oct 26, 2023
Obvious Unified Compression Helper is a CLI tool to help you compress and decompress files of several formats

Ouch! ouch stands for Obvious Unified Compression Helper and is a CLI tool to help you compress and decompress files of several formats. Features Usag

null 734 Dec 30, 2022
Introducing Inlyne, a GPU powered yet browsless tool to help you quickly view markdown files in the blink of an eye.

Inlyne - a GPU powered, browserless, markdown + html viewer inlyne README.md --theme dark/light About Markdown files are a wonderful tool to get forma

null 308 Jan 1, 2023
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.

Vikas Raj 117 Jan 3, 2023
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

Modular Font Editor K 3 Apr 26, 2022