From 2b217f1342c7a182603307baf05f87cc5f54cd93 Mon Sep 17 00:00:00 2001 From: Mario Voigt Date: Thu, 6 Jan 2022 20:38:17 +0100 Subject: [PATCH] add option to round up colors in cleanup styles extension --- .../cleanup_styles/cleanup_styles.inx | 11 ++-- .../cleanup_styles/cleanup_styles.py | 63 ++++++++++++++++++- 2 files changed, 67 insertions(+), 7 deletions(-) diff --git a/extensions/fablabchemnitz/cleanup_styles/cleanup_styles.inx b/extensions/fablabchemnitz/cleanup_styles/cleanup_styles.inx index 0a102bfb..b311a20f 100644 --- a/extensions/fablabchemnitz/cleanup_styles/cleanup_styles.inx +++ b/extensions/fablabchemnitz/cleanup_styles/cleanup_styles.inx @@ -20,12 +20,15 @@ false 100.0 - true - true - true - true + true + true + true + true true false + false + false + diff --git a/extensions/fablabchemnitz/cleanup_styles/cleanup_styles.py b/extensions/fablabchemnitz/cleanup_styles/cleanup_styles.py index ccaf147c..41553c7b 100644 --- a/extensions/fablabchemnitz/cleanup_styles/cleanup_styles.py +++ b/extensions/fablabchemnitz/cleanup_styles/cleanup_styles.py @@ -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'