add option to round up colors in cleanup styles extension

This commit is contained in:
Mario Voigt 2022-01-06 20:38:17 +01:00
parent e5ce6c2d1b
commit 2b217f1342
2 changed files with 67 additions and 7 deletions

View File

@ -20,12 +20,15 @@
</param>
<param name="stroke_opacity_override" type="bool" gui-text="Override stroke opacity">false</param>
<param name="stroke_opacity" type="float" precision="1" min="0.0" max="100.0" gui-text="Stroke opacity (%)">100.0</param>
<param name="reset_opacity" type="bool" gui-text="Reset opacity value in style attributes" gui-description="Reset stroke style attribute 'opacity'. Do not mix up with 'fill-opacity' and 'stroke-opacity'">true</param>
<param name="reset_stroke_attributes" type="bool" gui-text="Reset stroke* values in style attributes" gui-description="Remove stroke style attributes 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linejoin', 'stroke-linecap', 'stroke-miterlimit'">true</param>
<param name="reset_fill_attributes" type="bool" gui-text="Reset fill* value style attributes" gui-description="Sets 'fill:none;fill-opacity:1;' to style attribute">true</param>
<param name="apply_hairlines" type="bool" gui-text="Add additional hairline style" gui-description="Adds 'vector-effect:non-scaling-stroke;' and '-inkscape-stroke:hairline;' Hint: stroke-width is kept in background. All hairlines still have a valued width.">true</param>
<param name="reset_opacity" type="bool" gui-text="Reset opacity value in style attribute" gui-description="Reset stroke style attribute 'opacity'. Do not mix up with 'fill-opacity' and 'stroke-opacity'">true</param>
<param name="reset_stroke_attributes" type="bool" gui-text="Reset stroke* values in style attribute" gui-description="Remove 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linejoin', 'stroke-linecap', 'stroke-miterlimit' from style attribute">true</param>
<param name="reset_fill_attributes" type="bool" gui-text="Reset fill* values style attribute" gui-description="Sets 'fill:none;fill-opacity:1;' to style attribute">true</param>
<param name="apply_hairlines" type="bool" gui-text="Add additional hairline definition to style" gui-description="Adds 'vector-effect:non-scaling-stroke;' and '-inkscape-stroke:hairline;' Hint: stroke-width is kept in background. All hairlines still have a valued width.">true</param>
<param name="apply_black_strokes" type="bool" gui-text="Apply black strokes where strokes missing" gui-description="Adds 'stroke:#000000;' to style attribute">true</param>
<param name="remove_group_styles" type="bool" gui-text="Remove styles from groups" gui-description="Remove style attributes from parent groups. So we have styles directly at the level of visivle nodes!">false</param>
<param name="harmonize_colors" type="bool" gui-text="Harmonize colors" gui-description="Round up colors to the next 'full color'. Example: make rgb(253,0,0) to rgb(255,0,0) to receive clear red color.">false</param>
<param name="allow_half_tones" type="bool" gui-text="Allow half-tone colors" gui-description="Allow rounding up to half-tone colors">false</param>
<separator/>
<label>This extension works on current selection or for complete document</label>
</page>
<page name="tab_about" gui-text="About">

View File

@ -31,10 +31,28 @@ Notes:
import inkex
import re
import numpy as np
class CleanupStyles(inkex.EffectExtension):
groups = []
roundUpColors = []
roundUpColors = [
[ 0, 0, 0], #black | eri1
[ 0, 0, 255], #blue | eri2
[ 0, 255, 0], #green | eri3
[255, 0, 0], #red | eri4
[255, 0, 255], #magenta | eri5
[ 0, 255, 255], #cyan | eri6
[255, 255, 0], #yellow | eri7
#half tones
[128, 0, 255], #violet | eri8
[0 , 128, 255], #light blue | eri9
[255, 128, 0], #orange | eri10
[255, 0, 128], #pink | eri11
[128, 255, 0], #light green | eri12
[0 , 255, 128], #mint | eri13
]
def add_arguments(self, pars):
pars.add_argument("--tab")
@ -46,13 +64,43 @@ class CleanupStyles(inkex.EffectExtension):
pars.add_argument("--stroke_opacity_override", type=inkex.Boolean, default=False, help="Override stroke opacity")
pars.add_argument("--stroke_opacity", type=float, default="100.0", help="Stroke opacity (%)")
pars.add_argument("--reset_opacity", type=inkex.Boolean, default=True, help="Reset stroke style attribute 'opacity'. Do not mix up with 'fill-opacity' and 'stroke-opacity'")
pars.add_argument("--reset_stroke_attributes", type=inkex.Boolean, default=True, help="Remove stroke style attributes 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linejoin', 'stroke-linecap', 'stroke-miterlimit'")
pars.add_argument("--reset_stroke_attributes", type=inkex.Boolean, default=True, help="Remove 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linejoin', 'stroke-linecap', 'stroke-miterlimit' from style attribute")
pars.add_argument("--reset_fill_attributes", type=inkex.Boolean, default=True, help="Sets 'fill:none;fill-opacity:1;' to style attribute")
pars.add_argument("--apply_hairlines", type=inkex.Boolean, default=True, help="Adds 'vector-effect:non-scaling-stroke;' and '-inkscape-stroke:hairline;' Hint: stroke-width is kept in background. All hairlines still have a valued width.")
pars.add_argument("--apply_black_strokes", type=inkex.Boolean, default=True, help="Adds 'stroke:#000000;' to style attribute")
pars.add_argument("--remove_group_styles", type=inkex.Boolean, default=False, help="Remove styles from groups")
pars.add_argument("--harmonize_colors", type=inkex.Boolean, default=False, help="Round up colors to the next 'full color'. Example: make rgb(253,0,0) to rgb(255,0,0) to receive clear red color.")
pars.add_argument("--allow_half_tones", type=inkex.Boolean, default=False, help="Allow rounding up to half-tone colors")
def closestColor(self, colors, color):
colors = np.array(colors)
color = np.array(color)
distances = np.sqrt(np.sum((colors-color)**2, axis=1))
index_of_smallest = np.where(distances==np.amin(distances))
smallest_distance = colors[index_of_smallest]
return smallest_distance
def effect(self):
self.roundUpColors = [
[ 0, 0, 0], #black | eri1
[ 0, 0, 255], #blue | eri2
[ 0, 255, 0], #green | eri3
[255, 0, 0], #red | eri4
[255, 0, 255], #magenta | eri5
[ 0, 255, 255], #cyan | eri6
[255, 255, 0], #yellow | eri7
]
if self.options.allow_half_tones is True:
self.roundUpColors.extend([
[128, 0, 255], #violet | eri8
[0 , 128, 255], #light blue | eri9
[255, 128, 0], #orange | eri10
[255, 0, 128], #pink | eri11
[128, 255, 0], #light green | eri12
[0 , 255, 128], #mint | eri13
])
if len(self.svg.selected) == 0:
self.getAttribs(self.document.getroot())
else:
@ -71,7 +119,6 @@ class CleanupStyles(inkex.EffectExtension):
#stroke and fill styles can be included in style attribute or they can exist separately (can occure in older SVG files). We do not parse other attributes than style
def changeStyle(self, node):
#we check/modify the style of all shapes (not groups)
if isinstance(node, inkex.ShapeElement) and not isinstance(node, inkex.Group):
# the final styles applied to this element (with influence from top level elements like groups)
@ -163,6 +210,16 @@ class CleanupStyles(inkex.EffectExtension):
if val == 'none':
new_val = '#000000'
declarations[i] = prop + ':' + new_val
if self.options.harmonize_colors is True:
if prop == 'stroke' or prop == 'fill':
rgb = inkex.Color(val).to_rgb()
closest_color = self.closestColor(self.roundUpColors, [rgb[0], rgb[1], rgb[2]])
rgbNew = inkex.Color((
int(closest_color[0][0]),
int(closest_color[0][1]),
int(closest_color[0][2])
), space='rgb')
declarations[i] = prop + ':' + str(inkex.Color(rgbNew).to_named())
if self.options.reset_fill_attributes is True:
if prop == 'fill':
new_val = 'none'