convertColors plugin: Provide the ability to strip out ICC color profiles for better SVG 1.1 compatibility
Is your feature request related to a problem? Please describe. Some SVGs may contain ICC color profiles which is currently unsupported in browsers since it's a SVG 1.2 feature, and results in the SVG showing up as black by default when it's present and rendered in a browser.
Describe the solution you'd like The plugin should detect incompatible property values and use the fallback colour where possible.
Example regex that can be used to strip and use the fallback value. https://regex101.com/r/uhVFHA/1
Describe alternatives you've considered N/A
Additional context
- https://stackoverflow.com/questions/3405689/svg-image-with-cmyk-colours-is-it-possible
For those interested, you can clean up version 4.0 with this custom plugin to be placed in svgo.config.js :
{
name: 'dropColorProfile',
type: 'visitor',
fn: () => ({
element: {
enter: (node) => {
const dropTags = new Set([
'metadata',
'color-profile',
]);
// clean icc-color(...)
const colorAttrs = ['fill','stroke','stop-color','flood-color','lighting-color','color'];
for (const k of colorAttrs) {
const v = node.attributes?.[k];
if (typeof v === 'string' && /icc-color\(/i.test(v)) {
node.attributes[k] = v.replace(/\s*icc-color\([^)]*\)/gi, '').trim();
}
}
// clean style
if (typeof node.attributes?.style === 'string') {
let s = node.attributes.style;
s = s.replace(/\s*icc-color\([^)]*\)/gi, '');
s = s.replace(/(?:^|;)\s*(?:inkscape|sodipodi)-[^:]+:[^;]*;?/gi, '');
s = s.replace(/;;+/g, ';').replace(/^\s*;|;\s*$/g, '');
if (s) node.attributes.style = s; else delete node.attributes.style;
}
},
},
}),
}
For those interested, you can clean up version 4.0 with this custom plugin to be placed in svgo.config.js :
{
name: 'dropColorProfile',
type: 'visitor',
fn: () => ({
element: {
enter: (node) => {
const dropTags = new Set([
'metadata',
'color-profile',
]);
// clean icc-color(...)
const colorAttrs = ['fill','stroke','stop-color','flood-color','lighting-color','color'];
for (const k of colorAttrs) {
const v = node.attributes?.[k];
if (typeof v === 'string' && /icc-color\(/i.test(v)) {
node.attributes[k] = v.replace(/\s*icc-color\([^)]*\)/gi, '').trim();
}
}
// clean style
if (typeof node.attributes?.style === 'string') {
let s = node.attributes.style;
s = s.replace(/\s*icc-color\([^)]*\)/gi, '');
s = s.replace(/(?:^|;)\s*(?:inkscape|sodipodi)-[^:]+:[^;]*;?/gi, '');
s = s.replace(/;;+/g, ';').replace(/^\s*;|;\s*$/g, '');
if (s) node.attributes.style = s; else delete node.attributes.style;
}
},
},
}),
}
I don't think SVGO does anything special for SVG 1.1. One can only make a config to target it to somewhat extent.
I don't think SVGO does anything special for SVG 1.1. One can only make a config to target it to somewhat extent.