1
1
#!/usr/bin/env python3
2
2
# Used to generate some icons
3
- # Requires inkscape and imagemagick pacages
4
-
5
- import os , subprocess , colorsys
3
+ # Requires inkscape and imagemagick packages
4
+ import subprocess
5
+ import colorsys
6
+ import oxipng
6
7
from xml .etree import ElementTree as ET
7
8
8
- ICODIR = "./images/" # Directory with icons
9
- CICONS = "./images/controller-icons/" # Directory controller-icons
10
- RECOLORS = { # Defines set of hue shifts for controller-icons
9
+ ICODIR = "./images/" # Directory with icons
10
+ CICONS = "./images/controller-icons/" # Directory controller-icons
11
+ RECOLORS = {
12
+ # Defines set of hue shifts for controller-icons
11
13
# "0" : 0.0, # Green - original
12
14
"1" : 0.3 , # Blue
13
15
"2" : 0.7 , # Red
21
23
# Generate svg state icons
22
24
for size in (24 , 256 ):
23
25
for state in ('alive' , 'dead' , 'error' , 'unknown' ):
24
- print ("scc-statusicon-%s .png" % ( state ,) )
26
+ print (f "scc-statusicon-{ state } .png" )
25
27
subprocess .call ([
26
28
"inkscape" ,
27
- "%s/ scc-statusicon-%s .svg" % ( ICODIR , state ) ,
29
+ f" { ICODIR } scc-statusicon-{ state } .svg" ,
28
30
"--export-area-page" ,
29
- "--export-png=%s/%sx%s/ status/scc-%s .png" % ( ICODIR , size , size , state ) ,
30
- "--export-width=%s" % ( size ,) ,
31
- "--export-height=%s" % ( size ,) ])
32
-
31
+ f "--export-filename= { ICODIR } { size } x { size } / status/scc-{ state } .png" ,
32
+ f "--export-width={ size } " ,
33
+ f "--export-height={ size } " ])
34
+ oxipng . optimize ( f" { ICODIR } { size } x { size } /status/scc- { state } .png" , level = 6 , deflate = oxipng . Deflaters . zopfli ( 100 ))
33
35
34
- def html_to_rgb (html ) :
36
+ def html_to_rgb (html : str ) -> tuple [ int , int , int , int ] :
35
37
""" Converts #rrggbbaa or #rrggbb to r, g, b,a in (0,1) ranges """
36
38
html = html .strip ("#" )
37
39
if len (html ) == 6 :
@@ -40,15 +42,15 @@ def html_to_rgb(html):
40
42
return 0 , 0 , 0 , 0
41
43
elif len (html ) != 8 :
42
44
raise ValueError ("Needs RRGGBB(AA) format, got '%s'" % (html , ))
43
- return tuple (( float (int (html [i :i + 2 ],16 )) / 255.0 for i in xrange (0 , len (html ), 2 ) ))
45
+ return tuple (( float (int (html [i :i + 2 ],16 )) / 255.0 for i in range (0 , len (html ), 2 ) ))
44
46
45
47
46
- def rgb_to_html (r ,g ,b ):
48
+ def rgb_to_html (r ,g ,b ) -> str :
47
49
""" Convets rgb back to html color code """
48
50
return "#" + "" .join (( "%02x" % int (x * 255 ) for x in (r ,g ,b ) ))
49
51
50
52
51
- def recolor (tree , add ):
53
+ def recolor (tree , add ) -> None :
52
54
""" Recursive part of recolor_strokes and recolor_background """
53
55
if 'id' in tree .attrib and "overlay" in tree .attrib ['id' ]:
54
56
return
@@ -68,7 +70,8 @@ def recolor(tree, add):
68
70
h ,s ,v = colorsys .rgb_to_hsv (r ,g ,b )
69
71
# Shift hue
70
72
h += add
71
- while h > 1.0 : h -= 1.0
73
+ while h > 1.0 :
74
+ h -= 1.0
72
75
# Convert it back
73
76
r ,g ,b = colorsys .hsv_to_rgb (h ,s ,v )
74
77
# Store
@@ -80,13 +83,18 @@ def recolor(tree, add):
80
83
ET .register_namespace ("" ,"http://www.w3.org/2000/svg" )
81
84
for tp in ("sc" , "scbt" , "fake" , "ds4" , "hid" , "rpad" ):
82
85
# Read svg and parse it
83
- data = file ( "%s/%s -0.svg" % ( CICONS , tp ) , "r" ).read ()
86
+ data = open ( f" { CICONS } { tp } -0.svg" , "r" ).read ()
84
87
# Create recolored images
85
88
for key in RECOLORS :
86
89
tree = ET .fromstring (data )
87
90
# Walk recursively and recolor everything that has color
88
91
recolor (tree , RECOLORS [key ])
89
-
90
- out = "%s/%s-%s.svg" % (CICONS , tp , key )
91
- file (out , "w" ).write (ET .tostring (tree ))
92
+
93
+ out = f"{ CICONS } { tp } -{ key } .svg"
94
+ with open (out , "w" ) as file :
95
+ file .write (ET .tostring (tree ).decode ('utf-8' ))
96
+ subprocess .call ([
97
+ "svgo" ,
98
+ "--multipass" ,
99
+ f"--input={ out } " ])
92
100
print (out )
0 commit comments