├── utils ├── util.pyc ├── colorName.pyc ├── test.py ├── colorName.py └── util.py ├── Default (Linux).sublime-keymap ├── Default (Windows).sublime-keymap ├── packages.json ├── Commands.sublime-commands ├── ColorConvert.sublime-settings ├── .gitignore ├── CHANGELOG.md ├── Main.sublime-menu ├── README.md ├── Context.sublime-menu └── ColorConvert.py /utils/util.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obetame/ColorConvert/HEAD/utils/util.pyc -------------------------------------------------------------------------------- /utils/colorName.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/obetame/ColorConvert/HEAD/utils/colorName.pyc -------------------------------------------------------------------------------- /Default (Linux).sublime-keymap: -------------------------------------------------------------------------------- 1 | [ 2 | { "keys": ["ctrl+alt+c"], "command": "color_convert","args": {"value": "", "isSelect": true} } 3 | ] -------------------------------------------------------------------------------- /Default (Windows).sublime-keymap: -------------------------------------------------------------------------------- 1 | [ 2 | { "keys": ["ctrl+alt+c"], "command": "color_convert","args": {"value": "", "isSelect": true} } 3 | ] -------------------------------------------------------------------------------- /packages.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Color Convert", 3 | "details": "https://github.com/zhouyuexie/ColorConvert", 4 | "releases": [ 5 | { 6 | "sublime_text": "*", 7 | "tags": true 8 | } 9 | ] 10 | } -------------------------------------------------------------------------------- /Commands.sublime-commands: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "caption": "Preferences: ColorConvert Settings", 4 | "command": "edit_settings", "args": 5 | { 6 | "base_file": "${packages}/ColorConvert/ColorConvert.sublime-settings", 7 | "default": "// ColorConvert Settings - User\n{\n\t$0\n}\n" 8 | } 9 | } 10 | ] 11 | -------------------------------------------------------------------------------- /ColorConvert.sublime-settings: -------------------------------------------------------------------------------- 1 | { 2 | // default convert to rgb 3 | "convert_mode": "rgb", 4 | 5 | // convert value default is use capitalization 6 | "capitalization": false, 7 | 8 | // hex value is use android model, default to use css model 9 | "is_android": false, 10 | 11 | // allow loss transparent in hex_to_colorname. 12 | // false: #AARRGGBB or #RRGGBBAA will not be converted 13 | "loss_transparent": false 14 | } 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Numerous always-ignore extensions 2 | *.diff 3 | *.err 4 | *.orig 5 | *.log 6 | *.rej 7 | *.swo 8 | *.swp 9 | *.vi 10 | *.cache 11 | *~ 12 | *.pyc 13 | 14 | # OS or Editor folders 15 | .DS_Store 16 | Thumbs.db 17 | .cache 18 | .project 19 | .settings 20 | .tmproj 21 | *.esproj 22 | nbproject 23 | *.sublime-project 24 | *.sublime-workspace 25 | .tm_properties 26 | # Komodo 27 | *.komodoproject 28 | .komodotools 29 | 30 | # Folders to ignore 31 | .hg 32 | .svn 33 | .CVS 34 | .idea 35 | dist -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # CHANGELOG 2 | 3 | - 2.3.4 4 | - settings accessible via main menu and commands 5 | 6 | - 2.3.3 7 | - add config `loss_transparent`: allow loss transparent in hex_to_colorname. 8 | 9 | - 2.3.2 10 | - fixed: Output different hex formats based on different 'is_android' configurations 11 | 12 | - 2.3.1 13 | - Fixed bug with hex containing transparency in different locations on android and css. 14 | - Add config "is_android". 15 | 16 | - 2.3.0 17 | - Support transparent hexadecimal values ​​and rgba, hsla conversion. 18 | - Fixed issue where shorthand hexadecimal color values ​​cannot be converted to colorName. 19 | 20 | - 2.2.0 (2018/5/5) 21 | - Support css color name and hex conversion. 22 | - Support converting the CSS colorname in the entire file to hex. 23 | - Fix text display bug. 24 | 25 | - 2.1.0 (2018/4/25) 26 | - add feature (`hex_convert_to_colorname`) 27 | 28 | - 2.0.2 (2018/4/7) 29 | - release in [packagecontrol.io](https://packagecontrol.io/packages/Color%20Convert) -------------------------------------------------------------------------------- /Main.sublime-menu: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "caption": "Preferences", 4 | "id": "preferences", 5 | "mnemonic": "n", 6 | "children": [ 7 | { 8 | "caption": "Package Settings", 9 | "id": "package-settings", 10 | "mnemonic": "P", 11 | "children": [ 12 | { 13 | "caption": "ColorConvert", 14 | "children": [ 15 | { 16 | "caption": "Settings", 17 | "command": "edit_settings", "args": 18 | { 19 | "base_file": "${packages}/ColorConvert/ColorConvert.sublime-settings", 20 | "default": "// ColorConvert Settings - User\n{\n\t$0\n}\n" 21 | } 22 | } 23 | ] 24 | } 25 | ] 26 | } 27 | ] 28 | } 29 | ] 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ColorConvert 2 | 3 | sublime text 3 plug-in, Support `RGB`,`RGBA`,`HEX`,`HSL`,`HSLA`,`HSV`,`CMYK` to transform each other. 4 | 5 | ![DEMO](http://g.recordit.co/Rgi5FuhGaw.gif) 6 | 7 | ## Installation 8 | 9 | - You can easily install the plug-in through Package Control (https://packagecontrol.io/). 10 | 11 | - If you want to install this plug-in manually for some reason, simply clone this repo into your packages directory (make sure not to put it in the user sub dir). 12 | 13 | ## Instruction 14 | 15 | 1. Select a color declaration (e.g. '#008080', 'rgb(0,128,128)', or 'hsl(39.84,100.0%,25.1%)') 16 | 2. Mac user can use `cmd+alt+c`, Windows and Linux user can use `ctrl+alt+c` 17 | 18 | OR: 19 | 20 | 1. Select a color declaration 21 | 2. Right click and choose `ColorConvert`, click the mode you need to convert. 22 | 23 | ## Settings 24 | 25 | - `convert_mode`: convert to rgba mode, default `rgb` 26 | - `capitalization`: whether the converted letters need to be capitalized, default `false`. 27 | - `is_android`: Hex containing transparency is not the same format in android and css,if you are a Android Developer, please change it to `true`. 28 | - `loss_transparent`: allow loss transparent in hex_to_colorname, default false. 29 | 30 | ## Support 31 | 32 | - Support `RGB`,`RGBA`,`HEX`,`HSL`,`HSLA`,`HSV`,`CMYK` to convert each other. 33 | - Support [css3 color name](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value) convert to `HEX` 34 | - Support convert the color values in the entire page. 35 | - Support css color name and hex conversion 36 | 37 | ## Notes 38 | 39 | 1. Do not support css3 color:`transparent` and `currentColor`. 40 | 2. When `RGBA` is converted to other color value(like `RGB`,`HSL` etc...) it will lose the alpha value. 41 | 3. Some values are lost when some precision values are converted to CMYK and HSV, this is the result of the algorithm, so be careful in the process of using it. 42 | -------------------------------------------------------------------------------- /Context.sublime-menu: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "caption": "-" 4 | }, 5 | { 6 | "id": "ColorConvert", 7 | "caption": "ColorConvert", 8 | "children": [ 9 | { 10 | "caption": "Convert Selected Section", 11 | "command": "color_convert", 12 | "args": {"value": "", "isSelect": true} 13 | }, 14 | { 15 | "caption": "Convert Selected Section ->", 16 | "children":[ 17 | { 18 | "caption": "RGB", 19 | "command": "color_convert", 20 | "args": {"value": "rgb", "isSelect": true}, 21 | "checked": true 22 | }, 23 | { 24 | "caption": "RGBA", 25 | "command": "color_convert", 26 | "args": {"value": "rgba", "isSelect": true} 27 | }, 28 | { 29 | "caption": "HEX", 30 | "command": "color_convert", 31 | "args": {"value": "hex", "isSelect": true} 32 | }, 33 | { 34 | "caption": "HSL", 35 | "command": "color_convert", 36 | "args": {"value": "hsl", "isSelect": true} 37 | }, 38 | { 39 | "caption": "HSLA", 40 | "command": "color_convert", 41 | "args": {"value": "hsla", "isSelect": true} 42 | }, 43 | { 44 | "caption": "CMYK", 45 | "command": "color_convert", 46 | "args": {"value": "cmyk", "isSelect": true} 47 | }, 48 | { 49 | "caption": "HSV", 50 | "command": "color_convert", 51 | "args": {"value": "hsv", "isSelect": true} 52 | } 53 | ] 54 | }, 55 | { 56 | "caption": "Convert Selected ColorName<->HEX", 57 | "children": [ 58 | { 59 | "caption": "ColorName -> HEX", 60 | "command": "color_convert_name_to_hex" 61 | }, 62 | { 63 | "caption": "HEX -> ColorName", 64 | "command": "color_convert_hex_to_name" 65 | } 66 | ] 67 | }, 68 | { 69 | "caption": "-" 70 | }, 71 | { 72 | "caption": "Convert All", 73 | "command": "color_convert", 74 | "args": {"value": "", "isSelect": false} 75 | }, 76 | { 77 | "caption": "Convert All ->", 78 | "children":[ 79 | { 80 | "caption": "RGB", 81 | "command": "color_convert", 82 | "args": {"value": "rgb", "isSelect": false}, 83 | "checked": true 84 | }, 85 | { 86 | "caption": "RGBA", 87 | "command": "color_convert", 88 | "args": {"value": "rgba", "isSelect": false} 89 | }, 90 | { 91 | "caption": "HEX", 92 | "command": "color_convert", 93 | "args": {"value": "hex", "isSelect": false} 94 | }, 95 | { 96 | "caption": "HSL", 97 | "command": "color_convert", 98 | "args": {"value": "hsl", "isSelect": false} 99 | }, 100 | { 101 | "caption": "HSLA", 102 | "command": "color_convert", 103 | "args": {"value": "hsla", "isSelect": false} 104 | }, 105 | { 106 | "caption": "CMYK", 107 | "command": "color_convert", 108 | "args": {"value": "cmyk", "isSelect": false} 109 | }, 110 | { 111 | "caption": "HSV", 112 | "command": "color_convert", 113 | "args": {"value": "hsv", "isSelect": false} 114 | } 115 | ] 116 | }, 117 | { 118 | "caption": "Convert All Hex->ColorName", 119 | "command": "color_convert_all_hex_to_name" 120 | } 121 | ] 122 | }, 123 | { 124 | "caption": "-" 125 | } 126 | ] 127 | -------------------------------------------------------------------------------- /utils/test.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: UTF-8 -*- 3 | 4 | from util import * 5 | from colorName import * 6 | 7 | testValue = [{ 8 | "value": "rgb(81%,89%,12%)", 9 | "outputs": [ 10 | "rgb(81%,89%,12%)", 11 | "rgba(81%,89%,12%,1)", 12 | "hsl(66.23,77.78%,50.5%)", 13 | "hsla(66.23,77.78%,50.5%,1)", 14 | "#CEE21E", 15 | "cmyk(0.09,0,0.865,0.11)", 16 | "hsv(66,86.52%,89.0%)"] 17 | }, { 18 | "value": "rgba(81,89,12,0.3)", 19 | "outputs": [ 20 | "rgb(81,89,12)", 21 | "rgba(81,89,12,0.3)", 22 | "hsl(66.23,76.24%,19.8%)", 23 | "hsla(66.23,76.24%,19.8%,0.3)", 24 | "#51590C4C", 25 | "cmyk(0.09,0,0.865,0.651)", 26 | "hsv(66,86.52%,34.9%)"] 27 | }, { 28 | "value": "rgba(81%,89%,12%,0.3)", 29 | "outputs": [ 30 | "rgb(81%,89%,12%)", 31 | "rgba(81%,89%,12%,0.3)", 32 | "hsl(66.23,77.78%,50.5%)", 33 | "hsla(66.23,77.78%,50.5%,0.3)", 34 | "#CEE21E4C", 35 | "cmyk(0.09,0,0.865,0.11)", 36 | "hsv(66,86.52%,89.0%)"] 37 | }, { 38 | "value": "rgb(81,89,12)", 39 | "outputs": [ 40 | "rgb(81,89,12)", 41 | "rgba(81,89,12,1)", 42 | "hsl(66.23,76.24%,19.8%)", 43 | "hsla(66.23,76.24%,19.8%,1)", 44 | "#51590C", 45 | "cmyk(0.09,0,0.865,0.651)", 46 | "hsv(66,86.52%,34.9%)"] 47 | }, { 48 | "value": "hsl(400,100%,50%)", 49 | "outputs": [ 50 | "rgb(255,170,0)", 51 | "rgba(255,170,0,1)", 52 | "hsl(400,100%,50%)", 53 | "hsla(400,100%,50%,1)", 54 | "#FFAA00", 55 | "cmyk(0,0.333,1.0,0)", 56 | "hsv(40,100.0%,100.0%)"] 57 | }, { 58 | "value": "hsl(66.23,76.24%,19.8%)", 59 | "outputs": [ 60 | "rgb(81,89,12)", 61 | "rgba(81,89,12,1)", 62 | "hsl(66.23,76.24%,19.8%)", 63 | "hsla(66.23,76.24%,19.8%,1)", 64 | "#51590C", 65 | "cmyk(0.09,0,0.865,0.651)", 66 | "hsv(66,86.52%,34.9%)"] 67 | }, { 68 | "value": "hsla(66.23,76.24%,19.8%,1)", 69 | "outputs": [ 70 | "rgb(81,89,12)", 71 | "rgba(81,89,12,1)", 72 | "hsl(66.23,76.24%,19.8%)", 73 | "hsla(66.23,76.24%,19.8%,1)", 74 | "#51590CFF", 75 | "cmyk(0.09,0,0.865,0.651)", 76 | "hsv(66,86.52%,34.9%)"] 77 | }, { 78 | "value": "hsla(66.23,76.24%,19.8%,.3)", 79 | "outputs": [ 80 | "rgb(81,89,12)", 81 | "rgba(81,89,12,.3)", 82 | "hsl(66.23,76.24%,19.8%)", 83 | "hsla(66.23,76.24%,19.8%,.3)", 84 | "#51590C4C", 85 | "cmyk(0.09,0,0.865,0.651)", 86 | "hsv(66,86.52%,34.9%)"] 87 | }, { 88 | "value": "#51590C", 89 | "outputs": [ 90 | "rgb(81,89,12)", 91 | "rgba(81,89,12,1)", 92 | "hsl(66.23,76.24%,19.8%)", 93 | "hsla(66.23,76.24%,19.8%,1)", 94 | "#51590C", 95 | "cmyk(0.09,0,0.865,0.651)", 96 | "hsv(66,86.52%,34.9%)"] 97 | }, { 98 | "value": "#51590C55", 99 | "outputs": [ 100 | "rgb(81,89,12)", 101 | "rgba(81,89,12,0.3333)", 102 | "hsl(66.23,76.24%,19.8%)", 103 | "hsla(66.23,76.24%,19.8%,0.3333)", 104 | "#51590C55", 105 | "cmyk(0.09,0,0.865,0.651)", 106 | "hsv(66,86.52%,34.9%)"] 107 | }, { 108 | "value": "cmyk(0.09,0,0.865,0.651)", 109 | "outputs": [ 110 | "rgb(81,89,12)", 111 | "rgba(81,89,12,1)", 112 | "hsl(66.23,76.24%,19.8%)", 113 | "hsla(66.23,76.24%,19.8%,1)", 114 | "#51590C", 115 | "cmyk(0.09,0,0.865,0.651)", 116 | "hsv(66,86.52%,34.9%)"] 117 | }, { 118 | "value": "hsv(180,100%,50%)", 119 | "outputs": [ 120 | "rgb(0,128,128)", 121 | "rgba(0,128,128,1)", 122 | "hsl(180.0,100.0%,25.1%)", 123 | "hsla(180.0,100.0%,25.1%,1)", 124 | "#008080", 125 | "cmyk(1.0,0,0,0.498)", 126 | "hsv(180,100%,50%)"] 127 | }, { 128 | "value": "hsv(400,100%,50%)", 129 | "outputs": [ 130 | "rgb(128,85,0)", 131 | "rgba(128,85,0,1)", 132 | "hsl(39.84,100.0%,25.1%)", 133 | "hsla(39.84,100.0%,25.1%,1)", 134 | "#805500", 135 | "cmyk(0,0.336,1.0,0.498)", 136 | "hsv(400,100%,50%)"] 137 | }] 138 | 139 | convertAllModel = ['rgb', 'rgba', 'hsl', 'hsla', 'hex', 'cmyk', 'hsv'] 140 | 141 | def test(): 142 | for test in testValue: 143 | value = test['value'] 144 | outputs = test['outputs'] 145 | for n in range(7): 146 | output = convertColor(value, convertAllModel[n]) 147 | if (output != outputs[n]): 148 | print("Convert color: %s, Output value: %s,\nShould be: %s" % (value, output, outputs[n])) 149 | else: 150 | # print("Convert color: %s, Output value: %s" % (value, output)) 151 | pass 152 | 153 | def testOne(n): 154 | value = testValue[n]['value'] 155 | outputs = testValue[n]['outputs'] 156 | for n in range(7): 157 | output = convertColor(value, convertAllModel[n]) 158 | if (output != outputs[n]): 159 | print("Convert color: %s, Output value: %s,\nShould be: %s" % (value, output, outputs[n])) 160 | else: 161 | print("Convert color: %s, Output value: %s" % (value, output)) 162 | 163 | test() 164 | # testOne(4) -------------------------------------------------------------------------------- /ColorConvert.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: UTF-8 -*- 3 | 4 | import sublime 5 | import sublime_plugin 6 | import re 7 | from .utils import util 8 | from .utils import colorName 9 | 10 | matchRGBNumber = re.compile( r'\d{1,3}') 11 | 12 | """settings""" 13 | convertMode = 'rgb' 14 | capitalization = True 15 | isAndroid = False 16 | lossTransparent = False 17 | 18 | class ColorConvertCommand(sublime_plugin.TextCommand): 19 | # all value outputs 20 | outputs = [] 21 | # view and edit 22 | view = None 23 | edit = None 24 | # if innerConvertMode != "", must convert to innerConvertMode 25 | innerConvertMode = convertMode 26 | 27 | def __init__(self, view): 28 | # Load settings 29 | self.view = view 30 | global convertMode 31 | global capitalization 32 | global isAndroid 33 | global loss_transparent 34 | 35 | settings = sublime.load_settings("ColorConvert.sublime-settings") 36 | capitalization = settings.get("capitalization") 37 | lossTransparent = settings.get("loss_transparent") 38 | settings.add_on_change("convertMode", loadSettings) # addEventListener for convertMode 39 | settings.add_on_change("capitalization", loadSettings) # addEventListener for capitalization 40 | settings.add_on_change("isAndroid", loadSettings) 41 | settings.add_on_change("lossTransparent", loadSettings) 42 | 43 | loadSettings() 44 | 45 | # main 46 | def run(self, edit, value, isSelect): 47 | self.outputs = [] 48 | self.edit = edit 49 | 50 | if (value != ""): 51 | self.innerConvertMode = value 52 | else: 53 | self.innerConvertMode = convertMode 54 | 55 | # select section entry 56 | if isSelect: 57 | self.selectModeReplace(self.view.sel()) 58 | # all page(todo) 59 | else: 60 | self.allReplace() 61 | 62 | def handle(self, selectPart): 63 | # selectPart: '#1722DF' or 'rgba(0,0,0,1)' or 'hsla(100, 80.0%, 29.2%, 0.2)'... 64 | output = util.convertColor(selectPart, self.innerConvertMode, isAndroid) # core handle function 65 | 66 | if output != None: 67 | if capitalization: 68 | output = output.upper() 69 | self.outputs.append(output) 70 | 71 | """replace view select color""" 72 | def selectModeReplace(self, regions): 73 | """convert select section""" 74 | for region in regions: 75 | if not region.empty(): 76 | self.handle(self.view.substr(region)) 77 | 78 | for i, output in enumerate(self.outputs): 79 | for j, region in enumerate(regions): 80 | if i == j and not region.empty(): 81 | self.view.replace(self.edit, region, output) 82 | 83 | """replace view all color""" 84 | def allReplace(self): 85 | for name in ['rgb', 'rgba', 'hsl', 'hsla', 'hex', 'cmyk', 'hsv']: 86 | currentMatchRegion = self.view.find(util.matchRE.get(name), 0, sublime.IGNORECASE) 87 | allMatchRegin = self.view.find_all(util.matchRE.get(name), sublime.IGNORECASE) 88 | 89 | if name == self.innerConvertMode: 90 | continue 91 | 92 | for i in range(len(allMatchRegin)): 93 | if currentMatchRegion.empty(): 94 | continue 95 | 96 | output = util.convertColor(self.view.substr(currentMatchRegion), self.innerConvertMode, isAndroid) # core handle function 97 | if output != None: 98 | self.view.replace(self.edit, currentMatchRegion, convertCase(output)) 99 | 100 | currentMatchRegion = self.view.find(util.matchRE.get(name), currentMatchRegion.end(), sublime.IGNORECASE) 101 | 102 | class ColorConvertNameToHexCommand(sublime_plugin.TextCommand): 103 | """color name convert to hex 104 | """ 105 | 106 | def __init__(self, view): 107 | self.view = view 108 | 109 | # main 110 | def run(self, edit): 111 | self.edit = edit 112 | 113 | self.convertColorName() 114 | 115 | """convert color name""" 116 | def convertColorName(self): 117 | regions = self.view.sel() 118 | outputs = [] 119 | 120 | for region in regions: 121 | if not region.empty(): 122 | name = colorName.mapColorName.get(self.view.substr(region).lower(), self.view.substr(region)) 123 | output = colorName.colorName.get(name, name) 124 | 125 | if output != name: 126 | outputs.append(output) 127 | 128 | for i, output in enumerate(outputs): 129 | for j, region in enumerate(regions): 130 | if i == j and not region.empty(): 131 | self.view.replace(self.edit, region, convertCase(output)) 132 | 133 | class ColorConvertHexToNameCommand(sublime_plugin.TextCommand): 134 | """HEX convert To ColorName""" 135 | def __init__(self, view): 136 | self.view = view 137 | 138 | # main 139 | def run(self, edit): 140 | self.edit = edit 141 | 142 | self.covertColorName() 143 | 144 | def covertColorName(self): 145 | """covert color name""" 146 | regions = self.view.sel() 147 | outputs = [] 148 | hexsDict = colorName.getHexColorNameData() 149 | 150 | for region in regions: 151 | if not region.empty(): 152 | hexName = util.handleHEXValueString(self.view.substr(region), isAndroid, lossTransparent) 153 | 154 | if hexsDict.get(hexName): 155 | outputs.append(hexsDict.get(hexName)) 156 | 157 | for i, output in enumerate(outputs): 158 | for j, region in enumerate(regions): 159 | if i == j and not region.empty(): 160 | self.view.replace(self.edit, region, convertCase(output, True)) 161 | 162 | class ColorConvertAllHexToNameCommand(sublime_plugin.TextCommand): 163 | """all HEX convert To ColorName""" 164 | def __init__(self, view): 165 | self.view = view 166 | 167 | # main 168 | def run(self, edit): 169 | self.edit = edit 170 | 171 | self.covertColorName() 172 | 173 | def covertColorName(self): 174 | """covert color name""" 175 | currentMatchRegion = self.view.find(util.matchRE.get('hex'), 0, sublime.IGNORECASE) 176 | allMatchRegin = self.view.find_all(util.matchRE.get('hex'), sublime.IGNORECASE) 177 | hexsDict = colorName.getHexColorNameData() 178 | 179 | for i in range(len(allMatchRegin)): 180 | if currentMatchRegion.empty(): 181 | continue 182 | 183 | select = util.handleHEXValueString(self.view.substr(currentMatchRegion), isAndroid, lossTransparent) 184 | 185 | if select != None: 186 | hexName = hexsDict.get(select.upper()) 187 | if hexName: 188 | self.view.replace(self.edit, currentMatchRegion, convertCase(hexName, True)) 189 | 190 | currentMatchRegion = self.view.find(util.matchRE.get('hex'), currentMatchRegion.end(), sublime.IGNORECASE) 191 | 192 | def convertCase(value, isColorName = False): 193 | """Change case according to configuration 194 | 195 | Arguments: 196 | value {[str]} -- value data. 197 | isColorName {boolean} -- color name use Hump uppercase 198 | 199 | Returns: 200 | [str] -- Case value 201 | """ 202 | 203 | if capitalization: 204 | if isColorName: 205 | return colorName.mapColorName.get(value.lower()) 206 | return value.upper() 207 | 208 | return value.lower() 209 | 210 | def loadSettings(): 211 | """Loads settings from the ColorConvert.sublime-settings file""" 212 | 213 | global convertMode 214 | global capitalization 215 | global isAndroid 216 | global lossTransparent 217 | 218 | settings = sublime.load_settings("ColorConvert.sublime-settings") 219 | 220 | convertMode = settings.get("convert_mode") 221 | capitalization = settings.get("capitalization") 222 | isAndroid = settings.get("is_android") 223 | lossTransparent = settings.get("loss_transparent") -------------------------------------------------------------------------------- /utils/colorName.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: UTF-8 -*- 3 | 4 | colorName = { 5 | "AliceBlue": "#F0F8FF", 6 | "AntiqueWhite": "#FAEBD7", 7 | "Aqua": "#00FFFF", 8 | "Aquamarine": "#7FFFD4", 9 | "Azure": "#F0FFFF", 10 | "Beige": "#F5F5DC", 11 | "Bisque": "#FFE4C4", 12 | "Black": "#000000", 13 | "BlanchedAlmond": "#FFEBCD", 14 | "Blue": "#0000FF", 15 | "BlueViolet": "#8A2BE2", 16 | "Brown": "#A52A2A", 17 | "BurlyWood": "#DEB887", 18 | "CadetBlue": "#5F9EA0", 19 | "Chartreuse": "#7FFF00", 20 | "Chocolate": "#D2691E", 21 | "Coral": "#FF7F50", 22 | "CornflowerBlue": "#6495ED", 23 | "Cornsilk": "#FFF8DC", 24 | "Crimson": "#DC143C", 25 | "Cyan": "#00FFFF", 26 | "DarkBlue": "#00008B", 27 | "DarkCyan": "#008B8B", 28 | "DarkGoldenRod": "#B8860B", 29 | "DarkGray": "#A9A9A9", 30 | "DarkGreen": "#006400", 31 | "DarkKhaki": "#BDB76B", 32 | "DarkMagenta": "#8B008B", 33 | "DarkOliveGreen": "#556B2F", 34 | "Darkorange": "#FF8C00", 35 | "DarkOrchid": "#9932CC", 36 | "DarkRed": "#8B0000", 37 | "DarkSalmon": "#E9967A", 38 | "DarkSeaGreen": "#8FBC8F", 39 | "DarkSlateBlue": "#483D8B", 40 | "DarkSlateGray": "#2F4F4F", 41 | "DarkTurquoise": "#00CED1", 42 | "DarkViolet": "#9400D3", 43 | "DeepPink": "#FF1493", 44 | "DeepSkyBlue": "#00BFFF", 45 | "DimGray": "#696969", 46 | "DodgerBlue": "#1E90FF", 47 | "Feldspar": "#D19275", 48 | "FireBrick": "#B22222", 49 | "FloralWhite": "#FFFAF0", 50 | "ForestGreen": "#228B22", 51 | "Fuchsia": "#FF00FF", 52 | "Gainsboro": "#DCDCDC", 53 | "GhostWhite": "#F8F8FF", 54 | "Gold": "#FFD700", 55 | "GoldenRod": "#DAA520", 56 | "Gray": "#808080", 57 | "Green": "#008000", 58 | "GreenYellow": "#ADFF2F", 59 | "HoneyDew": "#F0FFF0", 60 | "HotPink": "#FF69B4", 61 | "IndianRed": "#CD5C5C", 62 | "Indigo": "#4B0082", 63 | "Ivory": "#FFFFF0", 64 | "Khaki": "#F0E68C", 65 | "Lavender": "#E6E6FA", 66 | "LavenderBlush": "#FFF0F5", 67 | "LawnGreen": "#7CFC00", 68 | "LemonChiffon": "#FFFACD", 69 | "LightBlue": "#ADD8E6", 70 | "LightCoral": "#F08080", 71 | "LightCyan": "#E0FFFF", 72 | "LightGoldenRodYellow": "#FAFAD2", 73 | "LightGrey": "#D3D3D3", 74 | "LightGreen": "#90EE90", 75 | "LightPink": "#FFB6C1", 76 | "LightSalmon": "#FFA07A", 77 | "LightSeaGreen": "#20B2AA", 78 | "LightSkyBlue": "#87CEFA", 79 | "LightSlateBlue": "#8470FF", 80 | "LightSlateGray": "#778899", 81 | "LightSteelBlue": "#B0C4DE", 82 | "LightYellow": "#FFFFE0", 83 | "Lime": "#00FF00", 84 | "LimeGreen": "#32CD32", 85 | "Linen": "#FAF0E6", 86 | "Magenta": "#FF00FF", 87 | "Maroon": "#800000", 88 | "MediumAquaMarine": "#66CDAA", 89 | "MediumBlue": "#0000CD", 90 | "MediumOrchid": "#BA55D3", 91 | "MediumPurple": "#9370D8", 92 | "MediumSeaGreen": "#3CB371", 93 | "MediumSlateBlue": "#7B68EE", 94 | "MediumSpringGreen": "#00FA9A", 95 | "MediumTurquoise": "#48D1CC", 96 | "MediumVioletRed": "#C71585", 97 | "MidnightBlue": "#191970", 98 | "MintCream": "#F5FFFA", 99 | "MistyRose": "#FFE4E1", 100 | "Moccasin": "#FFE4B5", 101 | "NavajoWhite": "#FFDEAD", 102 | "Navy": "#000080", 103 | "OldLace": "#FDF5E6", 104 | "Olive": "#808000", 105 | "OliveDrab": "#6B8E23", 106 | "Orange": "#FFA500", 107 | "OrangeRed": "#FF4500", 108 | "Orchid": "#DA70D6", 109 | "PaleGoldenRod": "#EEE8AA", 110 | "PaleGreen": "#98FB98", 111 | "PaleTurquoise": "#AFEEEE", 112 | "PaleVioletRed": "#D87093", 113 | "PapayaWhip": "#FFEFD5", 114 | "PeachPuff": "#FFDAB9", 115 | "Peru": "#CD853F", 116 | "Pink": "#FFC0CB", 117 | "Plum": "#DDA0DD", 118 | "PowderBlue": "#B0E0E6", 119 | "Purple": "#800080", 120 | "Red": "#FF0000", 121 | "RosyBrown": "#BC8F8F", 122 | "RoyalBlue": "#4169E1", 123 | "SaddleBrown": "#8B4513", 124 | "Salmon": "#FA8072", 125 | "SandyBrown": "#F4A460", 126 | "SeaGreen": "#2E8B57", 127 | "SeaShell": "#FFF5EE", 128 | "Sienna": "#A0522D", 129 | "Silver": "#C0C0C0", 130 | "SkyBlue": "#87CEEB", 131 | "SlateBlue": "#6A5ACD", 132 | "SlateGray": "#708090", 133 | "Snow": "#FFFAFA", 134 | "SpringGreen": "#00FF7F", 135 | "SteelBlue": "#4682B4", 136 | "Tan": "#D2B48C", 137 | "Teal": "#008080", 138 | "Thistle": "#D8BFD8", 139 | "Tomato": "#FF6347", 140 | "Turquoise": "#40E0D0", 141 | "Violet": "#EE82EE", 142 | "VioletRed": "#D02090", 143 | "Wheat": "#F5DEB3", 144 | "White": "#FFFFFF", 145 | "WhiteSmoke": "#F5F5F5", 146 | "Yellow": "#FFFF00", 147 | "YellowGreen": "#9ACD32", 148 | } 149 | 150 | mapColorName = { 151 | "blue": "Blue", 152 | "pink": "Pink", 153 | "powderblue": "PowderBlue", 154 | "darkorange": "Darkorange", 155 | "saddlebrown": "SaddleBrown", 156 | "slategray": "SlateGray", 157 | "indianred": "IndianRed", 158 | "fuchsia": "Fuchsia", 159 | "snow": "Snow", 160 | "lawngreen": "LawnGreen", 161 | "steelblue": "SteelBlue", 162 | "mediumslateblue": "MediumSlateBlue", 163 | "black": "Black", 164 | "aliceblue": "AliceBlue", 165 | "salmon": "Salmon", 166 | "crimson": "Crimson", 167 | "royalblue": "RoyalBlue", 168 | "white": "White", 169 | "navajowhite": "NavajoWhite", 170 | "cornsilk": "Cornsilk", 171 | "bisque": "Bisque", 172 | "palegreen": "PaleGreen", 173 | "brown": "Brown", 174 | "darkturquoise": "DarkTurquoise", 175 | "darkgreen": "DarkGreen", 176 | "mediumvioletred": "MediumVioletRed", 177 | "darkviolet": "DarkViolet", 178 | "darkgray": "DarkGray", 179 | "darkgoldenrod": "DarkGoldenRod", 180 | "mediumorchid": "MediumOrchid", 181 | "chocolate": "Chocolate", 182 | "purple": "Purple", 183 | "papayawhip": "PapayaWhip", 184 | "olive": "Olive", 185 | "lightslategray": "LightSlateGray", 186 | "darkmagenta": "DarkMagenta", 187 | "peachpuff": "PeachPuff", 188 | "tomato": "Tomato", 189 | "violet": "Violet", 190 | "mediumspringgreen": "MediumSpringGreen", 191 | "dodgerblue": "DodgerBlue", 192 | "aqua": "Aqua", 193 | "hotpink": "HotPink", 194 | "violetred": "VioletRed", 195 | "forestgreen": "ForestGreen", 196 | "lemonchiffon": "LemonChiffon", 197 | "mintcream": "MintCream", 198 | "seashell": "SeaShell", 199 | "goldenrod": "GoldenRod", 200 | "indigo": "Indigo", 201 | "cornflowerblue": "CornflowerBlue", 202 | "cadetblue": "CadetBlue", 203 | "lightyellow": "LightYellow", 204 | "darkblue": "DarkBlue", 205 | "limegreen": "LimeGreen", 206 | "deepskyblue": "DeepSkyBlue", 207 | "darkkhaki": "DarkKhaki", 208 | "lightgrey": "LightGrey", 209 | "whitesmoke": "WhiteSmoke", 210 | "yellow": "Yellow", 211 | "gainsboro": "Gainsboro", 212 | "sienna": "Sienna", 213 | "lavenderblush": "LavenderBlush", 214 | "sandybrown": "SandyBrown", 215 | "deeppink": "DeepPink", 216 | "feldspar": "Feldspar", 217 | "magenta": "Magenta", 218 | "silver": "Silver", 219 | "lime": "Lime", 220 | "darkcyan": "DarkCyan", 221 | "greenyellow": "GreenYellow", 222 | "darkorchid": "DarkOrchid", 223 | "lightsalmon": "LightSalmon", 224 | "lightgoldenrodyellow": "LightGoldenRodYellow", 225 | "olivedrab": "OliveDrab", 226 | "darkred": "DarkRed", 227 | "lightskyblue": "LightSkyBlue", 228 | "slateblue": "SlateBlue", 229 | "orange": "Orange", 230 | "chartreuse": "Chartreuse", 231 | "maroon": "Maroon", 232 | "peru": "Peru", 233 | "mediumturquoise": "MediumTurquoise", 234 | "aquamarine": "Aquamarine", 235 | "lightcoral": "LightCoral", 236 | "thistle": "Thistle", 237 | "red": "Red", 238 | "darkslategray": "DarkSlateGray", 239 | "khaki": "Khaki", 240 | "wheat": "Wheat", 241 | "lightslateblue": "LightSlateBlue", 242 | "lightpink": "LightPink", 243 | "burlywood": "BurlyWood", 244 | "lightseagreen": "LightSeaGreen", 245 | "mediumblue": "MediumBlue", 246 | "darksalmon": "DarkSalmon", 247 | "rosybrown": "RosyBrown", 248 | "blueviolet": "BlueViolet", 249 | "cyan": "Cyan", 250 | "mediumpurple": "MediumPurple", 251 | "midnightblue": "MidnightBlue", 252 | "firebrick": "FireBrick", 253 | "paleturquoise": "PaleTurquoise", 254 | "gray": "Gray", 255 | "palevioletred": "PaleVioletRed", 256 | "mediumseagreen": "MediumSeaGreen", 257 | "lightblue": "LightBlue", 258 | "coral": "Coral", 259 | "turquoise": "Turquoise", 260 | "ivory": "Ivory", 261 | "darkslateblue": "DarkSlateBlue", 262 | "lightgreen": "LightGreen", 263 | "linen": "Linen", 264 | "green": "Green", 265 | "beige": "Beige", 266 | "teal": "Teal", 267 | "azure": "Azure", 268 | "moccasin": "Moccasin", 269 | "orangered": "OrangeRed", 270 | "lightsteelblue": "LightSteelBlue", 271 | "tan": "Tan", 272 | "antiquewhite": "AntiqueWhite", 273 | "palegoldenrod": "PaleGoldenRod", 274 | "skyblue": "SkyBlue", 275 | "ghostwhite": "GhostWhite", 276 | "honeydew": "HoneyDew", 277 | "floralwhite": "FloralWhite", 278 | "dimgray": "DimGray", 279 | "seagreen": "SeaGreen", 280 | "lavender": "Lavender", 281 | "blanchedalmond": "BlanchedAlmond", 282 | "darkolivegreen": "DarkOliveGreen", 283 | "lightcyan": "LightCyan", 284 | "darkseagreen": "DarkSeaGreen", 285 | "mediumaquamarine": "MediumAquaMarine", 286 | "plum": "Plum", 287 | "gold": "Gold", 288 | "springgreen": "SpringGreen", 289 | "navy": "Navy", 290 | "mistyrose": "MistyRose", 291 | "orchid": "Orchid", 292 | "yellowgreen": "YellowGreen", 293 | "oldlace": "OldLace", 294 | } 295 | 296 | # get all color name 297 | def getColorNameArray(): 298 | return list(colorName) 299 | 300 | def getColorNameValue(name): 301 | return colorName[name] 302 | 303 | def getHexColorNameData(): 304 | """get hex and color name dict 305 | 306 | Returns: 307 | dict -- { 308 | hex: colorname 309 | } 310 | """ 311 | 312 | hexsDict = {} 313 | 314 | for key, value in colorName.items(): 315 | hexsDict[value] = key 316 | 317 | return hexsDict 318 | -------------------------------------------------------------------------------- /utils/util.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: UTF-8 -*- 3 | 4 | import re 5 | import math 6 | 7 | mapHEX = { 8 | 'A': 10, 9 | 'B': 11, 10 | 'C': 12, 11 | 'D': 13, 12 | 'E': 14, 13 | 'F': 15, 14 | '1': 1, 15 | '2': 2, 16 | '3': 3, 17 | '4': 4, 18 | '5': 5, 19 | '6': 6, 20 | '7': 7, 21 | '8': 8, 22 | '9': 9, 23 | '0': 0 24 | } 25 | 26 | mapRGB = { 27 | 0: '0', 28 | 1: '1', 29 | 2: '2', 30 | 3: '3', 31 | 4: '4', 32 | 5: '5', 33 | 6: '6', 34 | 7: '7', 35 | 8: '8', 36 | 9: '9', 37 | 10: 'A', 38 | 11: 'B', 39 | 12: 'C', 40 | 13: 'D', 41 | 14: 'E', 42 | 15: 'F' 43 | } 44 | 45 | matchNumber = re.compile(r'\d*\.*\d{1,3}\%*') 46 | isAndroidColor = False 47 | 48 | matchRE = { 49 | "rgb": r'rgb\([\s\.\d,%]*\)', 50 | "rgba": r'rgba\([\s\.\d,%]*\)', 51 | "hsl": r'hsl\([\s\.\d,%]*\)', 52 | "hsla": r'hsla\([\s\.\d,%]*\)', 53 | "hex": r'#[\da-zA-Z]{3,8}', 54 | "cmyk": r'cmyk\([\s\.\d,%]*\)', 55 | "hsv": r'hsv\([\s\.\d,%]*\)', 56 | } 57 | 58 | def getSelectValueMode(selectPart): 59 | """user select section value mode""" 60 | value = selectPart.upper() 61 | 62 | if 'RGBA' in value: 63 | return 'rgba' 64 | elif 'RGB' in value: 65 | return 'rgb' 66 | elif 'HSLA' in value: 67 | return 'hsla' 68 | elif 'HSL' in value: 69 | return 'hsl' 70 | elif 'CMYK' in value: 71 | return 'cmyk' 72 | elif 'HSV' in value: 73 | return 'hsv' 74 | else: 75 | return 'hex' 76 | 77 | # handle HEX 78 | def handleHEXValue(part): 79 | """ 80 | part -- #fff,#ffffff,#ffffff80,#80ffffff etc.. 81 | return -- ['f','f','f','f','f','f'],['f','f','f','f','f','f','8','0'] etc... 82 | """ 83 | if '#' not in part: 84 | return part 85 | 86 | value = part.split("#") 87 | if len(value) <= 1: 88 | value = value[0] 89 | else: 90 | value = value[1] 91 | 92 | letters = [] 93 | 94 | if len(value) == 3: 95 | for letter in value: 96 | letters.append(letter.upper()) 97 | letters.append(letter.upper()) 98 | elif len(value) == 6 or not isAndroidColor: 99 | for letter in value: 100 | letters.append(letter.upper()) 101 | elif isAndroidColor: 102 | for letter in value[2:]: 103 | letters.append(letter.upper()) 104 | letters.extend(value[:2]) 105 | 106 | return letters 107 | 108 | def getHexAlphaValue(part): 109 | """ 110 | Get hex's transparency value and convert to decimal 111 | part -- ['f','f','f','f','f','f','f','f'] 112 | return -- 1 113 | """ 114 | value = part[-2:] 115 | 116 | a = mapHEX.get(value[1].upper()) 117 | b = mapHEX.get(value[0].upper()) * 16 118 | 119 | return round((a + b) / 255.0, 4) 120 | 121 | def getRgbaAlphaValue(part): 122 | """ 123 | Get rgba transparency value and convert to hexadecimal 124 | part -- rgba(1,1,1,.5) 125 | return '80' 126 | """ 127 | alpha = float(part.split(',')[-1].replace(')', '')) 128 | toDecimal = alpha * 256 129 | 130 | if alpha == 1.0 or alpha > 1: 131 | return 'FF' 132 | 133 | b = int(toDecimal % 16) 134 | a = int(toDecimal / 16 % 16) 135 | 136 | return mapRGB.get(a) + mapRGB.get(b) 137 | 138 | def handleHEXValueString(part, isAndroid = False, lossTransparent = False): 139 | """ 140 | part -- #fff,#ffffff,#ffffff80,#80ffffff etc.. 141 | isAndroid -- Android color value hex transparency in front 142 | return -- #ffffff 143 | """ 144 | if '#' not in part: 145 | return '#' + part.upper() 146 | 147 | value = part.split("#") 148 | if len(value) <= 1: 149 | value = value[0] 150 | else: 151 | value = value[1] 152 | 153 | letters = '#' 154 | 155 | if len(value) == 3: 156 | for letter in value: 157 | letters += letter.upper() 158 | letters += letter.upper() 159 | elif len(value) == 6 or not lossTransparent: 160 | letters = letters + value.upper() 161 | else: 162 | # len = 8 163 | if isAndroid: 164 | letters = letters + value.upper()[2:] 165 | else: 166 | letters = letters + value.upper()[:-2] 167 | 168 | return letters 169 | 170 | # handle RGB 171 | def handleRGBValue(selectPart): 172 | value = matchNumber.findall(selectPart) 173 | 174 | newValue = [] 175 | """handle number is '.5' a class """ 176 | for v in value: 177 | if v[0] == ".": 178 | newValue.append(float("0." + v[1:])) 179 | elif "%" in v: 180 | number = float(v.split("%")[0]) # 89% -> 89 181 | newValue.append(number / 100) 182 | else: 183 | newValue.append(float(v) / 255) 184 | return newValue 185 | 186 | # handle HSL 187 | def handleHSLValue(selectPart): 188 | value = matchNumber.findall(selectPart) 189 | 190 | newValue = [] 191 | """handle number is '.5' a class """ 192 | for v in value: 193 | if v[0] == ".": 194 | newValue.append(float("0." + v[1:])) 195 | elif "%" in v: 196 | newValue.append(int(v.split("%")[0])) 197 | else: 198 | newValue.append(int(v)) 199 | return newValue 200 | 201 | # HEX to RGB 202 | def HEX2RGB(selectPart, isAlpha = False, alpha = 1): 203 | lettersArray = handleHEXValue(selectPart) 204 | 205 | rgb = '' 206 | for n in list(range(0, 5, 2)): 207 | valueArray = lettersArray[n : n + 2] 208 | rgb += str(mapHEX[valueArray[0]] * 16 + mapHEX[valueArray[1]]) + ',' 209 | 210 | if isAlpha: 211 | if len(lettersArray) == 8: 212 | """include alpha value""" 213 | alphaValue = getHexAlphaValue(lettersArray) 214 | 215 | return 'rgba(' + rgb[:-1] + "," + str(alphaValue) + ')' 216 | else: 217 | return 'rgba(' + rgb[:-1] + "," + str(alpha) + ')' 218 | else: 219 | return 'rgb(' + rgb[:-1] + ')' 220 | 221 | # RGB to HEX 222 | def RGB2HEX(selectPart, isAlpha = False): 223 | numberArray = handleRGBValue(selectPart) 224 | 225 | valueArray = [] 226 | for value in numberArray: 227 | valueArray.append(value * 255) 228 | 229 | hexValue = '' 230 | for n in list(range(0,3)): 231 | number = valueArray[n] 232 | if (number == 0): 233 | hexValue += '00' 234 | continue 235 | 236 | first = int(number / 16) 237 | secend = int(number % 16) 238 | hexValue += (mapRGB[first] + mapRGB[secend]) 239 | 240 | if isAlpha and len(numberArray) == 4: 241 | if isAndroidColor: 242 | hexValue = getRgbaAlphaValue(selectPart) + hexValue 243 | else: 244 | hexValue += getRgbaAlphaValue(selectPart) 245 | 246 | return '#' + hexValue 247 | 248 | # RGB to RGBA 249 | def RGB_HSL2RGBA_HSLA(selectPart, input, output): 250 | value = selectPart[:-1] + ",1)" 251 | return value.replace(input, output) 252 | 253 | # RGBA to RGB 254 | def RGBA_HSLA2RGB_HSL(selectPart, input, output): 255 | valueArray = selectPart.split(",") 256 | valueArray[3] = ")" 257 | 258 | return ",".join(valueArray).replace(input, output)[:-2] + ")" 259 | 260 | def RGB2HSL(selectPart, isAlpha = False, alpha = 1): 261 | # RGB to HSL 262 | numberArray = handleRGBValue(selectPart) 263 | maxN = max(numberArray) 264 | minN = min(numberArray) 265 | h = "" 266 | s = "" 267 | l = (maxN + minN) / 2 268 | 269 | if maxN == minN: 270 | h = s = 0 271 | else: 272 | mid = maxN - minN 273 | if l > 0.5: 274 | s = mid / (2 - maxN - minN) 275 | elif l <= 0.5 and l > 0: 276 | s = mid / (maxN + minN) 277 | elif l == 0: 278 | s = 0 279 | 280 | if maxN == numberArray[0] and numberArray[1] >= numberArray[2]: 281 | h = 60 * (numberArray[1] - numberArray[2]) / mid + 0 282 | elif maxN == numberArray[0] and numberArray[1] < numberArray[2]: 283 | h = 60 * (numberArray[1] - numberArray[2]) / mid + 360 284 | elif maxN == numberArray[1]: 285 | h = 60 * (numberArray[2] - numberArray[0]) / mid + 120 286 | elif maxN == numberArray[2]: 287 | h = 60 * (numberArray[2] - numberArray[0]) / mid + 120 288 | 289 | if isAlpha: 290 | return "hsla(%s,%s%%,%s%%,%s)" % (str(round(h, 2)), str(round(s * 100, 2)), str(round(l * 100, 2)), str(alpha)) 291 | else: 292 | return "hsl(%s,%s%%,%s%%)" % (str(round(h, 2)), str(round(s * 100, 2)), str(round(l * 100, 2))) 293 | 294 | def RGBA2HSL(selectPart): 295 | """RGBA to HSL 296 | https://stackoverflow.com/questions/2353211/hsl-to-rgb-color-conversion 297 | """ 298 | value = ','.join(selectPart.split(',')[:-1]) + ")" 299 | return RGB2HSL(value) 300 | 301 | def RGBA2HSLA(selectPart): 302 | # RGBA to HSLA 303 | valueArray = selectPart.split(',') 304 | value = ','.join(valueArray[:-1]) + ")" 305 | 306 | return RGB2HSL(value, True, valueArray[-1][:-1]) 307 | 308 | def handleHSL(p, q, t): 309 | # handle hsl 310 | pi = p 311 | qi = q 312 | ti = t 313 | 314 | if ti < 0: 315 | ti += 1 316 | if ti > 1: 317 | ti -= 1 318 | if ti < 0.166666666: 319 | return pi + (qi - pi) * 6 * ti 320 | if ti < 0.5: 321 | return qi 322 | if ti < 0.666666666: 323 | return pi + (qi - pi) * (0.666666666 - ti) * 6 324 | return pi 325 | 326 | def HSL2RGB(selectPart, isAlpha = False, alpha = 1): 327 | # hsl to rgb 328 | valueArray = matchNumber.findall(selectPart) 329 | 330 | r = g = b = None 331 | 332 | h = float(valueArray[0]) 333 | s = float(valueArray[1].split('%')[0]) / 100 334 | l = float(valueArray[2].split('%')[0]) / 100 335 | 336 | if h >= 360: 337 | h -= 360 338 | h = h / 360 339 | 340 | if len(valueArray) == 4: 341 | alpha = valueArray[3] 342 | 343 | if s == 0: 344 | r = g = b = l 345 | else: 346 | q = p = None 347 | if l < 0.5: 348 | q = l * (1 + s) 349 | else: 350 | q = l + s - l * s 351 | p = 2 * l - q 352 | r = round(handleHSL(p, q, h + 0.33333333) * 255) 353 | g = round(handleHSL(p, q, h) * 255) 354 | b = round(handleHSL(p, q, h - 0.33333333) * 255) 355 | 356 | if isAlpha: 357 | if len(valueArray) == 4: 358 | return "rgba(%d,%d,%d,%s)" % (int(r),int(g),int(b),valueArray[-1]) 359 | return "rgba(%d,%d,%d,%s)" % (int(r),int(g),int(b),str(alpha)) 360 | else: 361 | return "rgb(%d,%d,%d)" % (int(r),int(g),int(b)) 362 | 363 | def RGB2CMYK(selectPart): 364 | """RGB TO CMYK 365 | https://www.rapidtables.com/convert/color/rgb-to-cmyk.html 366 | """ 367 | numberArray = handleRGBValue(selectPart) 368 | 369 | r = numberArray[0] 370 | g = numberArray[1] 371 | b = numberArray[2] 372 | 373 | k = round(1 - max(numberArray), 3) 374 | 375 | if 1 - k == 0: 376 | return "cmyk(%s,%s,%s,%s)" % (str(0),str(0),str(0),str(1)) 377 | 378 | c = round((1 - r - k) / (1 - k), 3) 379 | m = round((1 - g - k) / (1 - k), 3) 380 | y = round((1 - b - k) / (1 - k), 3) 381 | 382 | value = [c,m,y,k] 383 | for i,n in enumerate(value): 384 | if n <= 0: 385 | # fixed "-0.0" 386 | value[i] = 0 387 | 388 | return "cmyk(%s,%s,%s,%s)" % (str(value[0]),str(value[1]),str(value[2]),str(value[3])) 389 | 390 | def CMYK2RGB(selectPart, isAlpha = False, alpha = 1): 391 | """CMYK TO RGB 392 | https://www.rapidtables.com/convert/color/cmyk-to-rgb.html 393 | """ 394 | valueArray = matchNumber.findall(selectPart) 395 | 396 | c = float(valueArray[0]) 397 | m = float(valueArray[1]) 398 | y = float(valueArray[2]) 399 | k = float(valueArray[3]) 400 | 401 | r = int(round(255 * (1 - c) * (1 - k))) 402 | g = int(round(255 * (1 - m) * (1 - k))) 403 | b = int(round(255 * (1 - y) * (1 - k))) 404 | 405 | if isAlpha: 406 | return "rgba(%d,%d,%d,%s)" % (r,g,b,str(alpha)) 407 | else: 408 | return "rgb(%d,%d,%d)" % (r,g,b) 409 | 410 | def RGB2HSV(selectPart): 411 | """RGB TO HSV 412 | https://www.rapidtables.com/convert/color/rgb-to-hsv.html 413 | """ 414 | numberArray = handleRGBValue(selectPart) 415 | 416 | # remove alpha 417 | if len(numberArray) > 3: 418 | numberArray = numberArray[:-1] 419 | 420 | r = numberArray[0] 421 | g = numberArray[1] 422 | b = numberArray[2] 423 | h = s = v = 0 424 | 425 | cmax = max(numberArray) 426 | cmin = min(numberArray) 427 | mid = cmax - cmin 428 | 429 | if mid == 0: 430 | h = 0 431 | elif cmax == r: 432 | h = 60 * (((g - b) / mid) % 6) 433 | elif cmax == g: 434 | h = 60 * ((b - r) / mid + 2) 435 | elif cmax == b: 436 | h = 60 * ((r - g) / mid + 4) 437 | 438 | if cmax == 0: 439 | s = 0 440 | else: 441 | s = mid / cmax 442 | 443 | v = cmax 444 | 445 | return "hsv(%d,%s%%,%s%%)" % (h,str(round(s * 100, 2)),str(round(v * 100, 2))) 446 | 447 | def HSV2RGB(selectPart, isAlpha = False, alpha = 1): 448 | """HSV TO RGB 449 | https://www.rapidtables.com/convert/color/hsl-to-rgb.html 450 | """ 451 | valueArray = matchNumber.findall(selectPart) 452 | 453 | h = float(valueArray[0]) 454 | s = float(valueArray[1].split('%')[0]) / 100 455 | v = float(valueArray[2].split('%')[0]) / 100 456 | 457 | if h >= 360: 458 | h -= 360 459 | 460 | c = v * s 461 | x = c * (1 - math.fabs((h / 60) % 2 - 1)) 462 | m = v - c 463 | 464 | r = g = b = 0 465 | 466 | if h >= 0 and h < 60: 467 | r = c 468 | g = x 469 | b = 0 470 | elif h >= 60 and h < 120: 471 | r = x 472 | g = c 473 | b = 0 474 | elif h >= 120 and h < 180: 475 | r = 0 476 | g = c 477 | b = x 478 | elif h >= 180 and h < 240: 479 | r = 0 480 | g = x 481 | b = c 482 | elif h >= 240 and h < 300: 483 | r = x 484 | g = 0 485 | b = c 486 | elif h >= 300 and h < 360: 487 | r = c 488 | g = 0 489 | b = x 490 | 491 | R = round((r + m) * 255) 492 | G = round((g + m) * 255) 493 | B = round((b + m) * 255) 494 | 495 | if isAlpha: 496 | return "rgba(%d,%d,%d,%s)" % (R,G,B, str(alpha)) 497 | else: 498 | return "rgb(%d,%d,%d)" % (R,G,B) 499 | 500 | switcher = { 501 | "rgb": { 502 | "rgb": lambda value: value, 503 | "rgba": lambda value: RGB_HSL2RGBA_HSLA(value, 'rgb', 'rgba'), 504 | "hex": RGB2HEX, 505 | "hsl": RGB2HSL, 506 | "hsla": lambda value: RGB2HSL(value, isAlpha = True), 507 | "cmyk": RGB2CMYK, 508 | "hsv": RGB2HSV 509 | }, 510 | "rgba": { 511 | "rgb": lambda value: RGBA_HSLA2RGB_HSL(value, 'rgba', 'rgb'), 512 | "rgba": lambda value: value, 513 | "hex": lambda value: RGB2HEX(value, isAlpha = True), 514 | "hsl": RGBA2HSL, 515 | "hsla": RGBA2HSLA, 516 | "cmyk": RGB2CMYK, 517 | "hsv": RGB2HSV 518 | }, 519 | "hsl": { 520 | "rgb": HSL2RGB, 521 | "rgba": lambda value: HSL2RGB(value, isAlpha = True), 522 | "hex": lambda value: RGB2HEX(HSL2RGB(value)), 523 | "hsl": lambda value: value, 524 | "hsla": lambda value: RGB_HSL2RGBA_HSLA(value, 'hsl', 'hsla'), 525 | "cmyk": lambda value: RGB2CMYK(HSL2RGB(value)), 526 | "hsv": lambda value: RGB2HSV(HSL2RGB(value)) 527 | }, 528 | "hsla": { 529 | "rgb": HSL2RGB, 530 | "rgba": lambda value: HSL2RGB(value, isAlpha = True), 531 | "hex": lambda value: RGB2HEX(HSL2RGB(value, isAlpha = True), isAlpha = True), 532 | "hsl": lambda value: RGBA_HSLA2RGB_HSL(value, 'hsla', 'hsl'), 533 | "hsla": lambda value: value, 534 | "cmyk": lambda value: RGB2CMYK(HSL2RGB(value)), 535 | "hsv": lambda value: RGB2HSV(HSL2RGB(value)) 536 | }, 537 | "hex": { 538 | "rgb": HEX2RGB, 539 | "rgba": lambda value: HEX2RGB(value, isAlpha = True), 540 | "hex": lambda value: value, 541 | "hsl": lambda value: RGB2HSL(HEX2RGB(value)), 542 | "hsla": lambda value: RGBA2HSLA(HEX2RGB(value, isAlpha = True)), 543 | "cmyk": lambda value: RGB2CMYK(HEX2RGB(value)), 544 | "hsv": lambda value: RGB2HSV(HEX2RGB(value)) 545 | }, 546 | "cmyk": { 547 | "rgb": CMYK2RGB, 548 | "rgba": lambda value: CMYK2RGB(value, isAlpha = True), 549 | "hex": lambda value: RGB2HEX(CMYK2RGB(value)), 550 | "hsl": lambda value: RGB2HSL(CMYK2RGB(value)), 551 | "hsla": lambda value: RGB_HSL2RGBA_HSLA(RGB2HSL(CMYK2RGB(value)), 'hsl', 'hsla'), 552 | "cmyk": lambda value: value, 553 | "hsv": lambda value: RGB2HSV(CMYK2RGB(value)) 554 | }, 555 | "hsv": { 556 | "rgb": HSV2RGB, 557 | "rgba": lambda value: HSV2RGB(value, isAlpha = True), 558 | "hex": lambda value: RGB2HEX(HSV2RGB(value)), 559 | "hsl": lambda value: RGB2HSL(HSV2RGB(value)), 560 | "hsla": lambda value: RGB_HSL2RGBA_HSLA(RGB2HSL(HSV2RGB(value)), 'hsl', 'hsla'), 561 | "cmyk": lambda value: RGB2CMYK(HSV2RGB(value)), 562 | "hsv": lambda value: value 563 | } 564 | } 565 | 566 | def convertColor(selectPart, convertMode, isAndroid = False): 567 | """value(selectPart) convert to need mode(convertMode)""" 568 | global isAndroidColor 569 | isAndroidColor = isAndroid 570 | 571 | valueMode = getSelectValueMode(selectPart) 572 | 573 | if valueMode == 'hex': 574 | length = len(selectPart) 575 | if length != 4 and length != 7 and length != 9: 576 | return None 577 | 578 | handleObj = switcher.get(valueMode, {}) 579 | handleFun = handleObj.get(convertMode, lambda value: value) 580 | 581 | return handleFun(selectPart) 582 | --------------------------------------------------------------------------------