archive- Random tools & helpful resources for IRC |
git clone git://git.acid.vegas/archive.git |
Log | Files | Refs | Archive |
img2irc_perplexa.py (4413B)
1 #!/usr/bin/env python 2 # -*- coding: utf-8 -*- 3 4 """ 5 img2irc 6 Copyright (C) 2012 perplexa 7 """ 8 9 __author__ = "perplexa" 10 __version__ = "0.3" 11 12 import sys 13 if sys.version_info[:2] < (2, 6): 14 raise RuntimeError("Python v2.6 or later required") 15 16 # requires python image library 17 import Image 18 import getopt 19 import StringIO 20 import sys 21 import time 22 import urllib2 23 24 # define our palettes 25 palette = { 26 "mirc": { 27 0: [255,255,255], 28 1: [0,0,0], 29 2: [0,0,127], 30 3: [0,147,0], 31 4: [255,0,0], 32 5: [127,0,0], 33 6: [156,0,156], 34 7: [252,127,0], 35 8: [255,255,0], 36 9: [0,252,0], 37 10: [0,147,147], 38 11: [0,255,255], 39 12: [0,0,252], 40 13: [255,0,255], 41 14: [127,127,127], 42 15: [210,210,210] 43 }, 44 "perplexa": { 45 0: [255,255,255], 46 1: [0,0,0], 47 2: [58,80,120], 48 3: [174,206,146], 49 4: [207,97,113], 50 5: [158,24,40], 51 6: [150,60,89], 52 7: [150,138,56], 53 8: [255,247,150], 54 9: [197,247,121], 55 10: [65,129,121], 56 11: [113,190,190], 57 12: [65,134,190], 58 13: [207,158,190], 59 14: [102,102,102], 60 15: [190,190,190] 61 } 62 } 63 64 # define default parameter values 65 use_palette = "perplexa" 66 line_delay = None 67 max_width = None 68 69 #convert RGB to CIE-L*a*b* color space (takes floats between 0.0-1.0) 70 def rgb_to_cielab(r, g, b): 71 return xyz_to_cielab(*rgb_to_xyz(r, g, b)) 72 73 def rgb_to_xyz(r, g, b): 74 r = _r1(r) 75 g = _r1(g) 76 b = _r1(b) 77 78 # observer. = 2°, illuminant = D65 79 x = r * 0.4124 + g * 0.3576 + b * 0.1805 80 y = r * 0.2126 + g * 0.7152 + b * 0.0722 81 z = r * 0.0193 + g * 0.1192 + b * 0.9505 82 83 return x, y, z 84 85 def _r1(y): 86 y = ((y + 0.055) / 1.055) ** 2.4 if y > 0.04045 else y / 12.92 87 return y * 100 88 89 def _r2(y): 90 return y ** (1.0 / 3.0) if y > 0.008856 else (7.787 * y) + (16.0 / 116.0) 91 92 def xyz_to_cielab(x, y, z): 93 x = x / 95.047 94 y = y / 100.0 95 z = z / 108.883 96 97 x = _r2(x) 98 y = _r2(y) 99 z = _r2(z) 100 101 L = (116 * y) - 16 102 a = 500 * (x - y) 103 b = 200 * (y - z) 104 105 return L, a, b 106 107 def euclidian_distance(v1, v2): 108 return sum((a - b) ** 2 for a, b in zip(v1, v2)) ** 0.5 109 110 def nearest_color(lab): 111 distance = None 112 color = None 113 for col in palette[use_palette]: 114 clab = rgb_to_cielab(*[x / 255.0 for x in palette[use_palette][col]]) 115 cdist = euclidian_distance(clab, lab) 116 if distance == None or cdist < distance: 117 distance = cdist 118 color = col 119 return color 120 121 def usage(): 122 return """Usage: %s [OPTIONS] IMAGE 123 Convert IMAGE to IRC text. 124 125 Options: 126 -d, --delay define delay per line (seconds, float) 127 -p, --palette use specific palette (%s) 128 -w, --width limit image width to X pixels 129 """ % (sys.argv[0], ", ".join(palette.keys())) 130 131 # ## ### ##### ######## ##### ### ## # 132 # ## ### ##### ######## ##### ### ## # 133 134 if __name__ == "__main__": 135 try: 136 opts, args = getopt.getopt(sys.argv[1:], "p:d:w:", ["palette=", "delay=", "width="]) 137 except getopt.GetoptError, err: 138 sys.stderr.write(str(err) + "\n") 139 sys.exit(2) 140 141 for opt, arg in opts: 142 if opt in ("-p", "--palette"): 143 if arg not in palette: 144 sys.stderr.write("Invalid palette: %s\nUse one of the following: %s\n" % (arg, ", ".join(palette.keys()))) 145 sys.exit(2) 146 use_palette = arg 147 148 if opt in ("-d", "--delay"): 149 line_delay = float(arg) 150 151 if opt in ("-w", "--width"): 152 max_width = int(arg) 153 154 if not len(args): 155 sys.stderr.write(usage()) 156 sys.exit(2) 157 fn = args[0] 158 159 try: 160 if fn[0:4] == "http": 161 sock = urllib2.urlopen(fn) 162 data = sock.read() 163 sock.close() 164 fil = StringIO.StringIO(data) 165 else: 166 fil = fn 167 img = Image.open(fil) 168 except: 169 sys.stderr.write("Could not open file: %s\n" % fn) 170 sys.exit(2) 171 172 img = img.convert(mode="RGBA") 173 174 bg = Image.new("RGBA", img.size, (255, 255, 255)) 175 bg.paste(img, img) 176 177 width, height = bg.size 178 if max_width: 179 height = int(height * (max_width / float(width))) 180 width = max_width 181 bg = bg.resize((width, height)) 182 183 pxl = bg.load() 184 prv = None 185 186 for y in range(height): 187 for x in range(width): 188 r, g, b, a = pxl[x, y] 189 col = nearest_color(rgb_to_cielab(r / 255.0, g / 255.0, b / 255.0)) 190 if prv == None or prv != col: 191 sys.stdout.write("\x03%s,%sXX" % (col, col)) 192 prv = col 193 else: 194 sys.stdout.write("XX") 195 sys.stdout.write("\n") 196 prv = None 197 198 if line_delay: 199 sys.stdout.flush() 200 time.sleep(line_delay)