Created
July 19, 2015 18:57
-
-
Save kmansoft/b206c1f4d7ac9e4601fc to your computer and use it in GitHub Desktop.
A script to convert "material dark" icons to "material" icons, by adjusting the alpha value. The right adjustment seems to be 140 (= increase by 40%).
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
import sys | |
import argparse | |
import os | |
import re | |
import png | |
MAPPING = { | |
"drawable-mdpi" : "drawable-mdpi", | |
"drawable-hdpi" : "drawable-hdpi", | |
"drawable-xhdpi" : "drawable-xhdpi-v14", | |
"drawable-xxhdpi" : "drawable-xxhdpi-v14", | |
# more | |
"mdpi" : "drawable-mdpi", | |
"hdpi" : "drawable-hdpi", | |
"xhdpi" : "drawable-xhdpi-v14", | |
"xxhdpi" : "drawable-xxhdpi-v14", | |
} | |
class Scaler: | |
def __init__(self, scale): | |
self.scale = scale | |
def apply(self, alpha): | |
alpha = alpha * scale / 100 | |
if alpha > 255: | |
alpha = 255 | |
return alpha | |
def shorten_path_pair(path1, path2): | |
common = os.path.commonprefix([path1, path2]) | |
if common == path1: | |
return os.path.basename(path1) | |
return "{0} -> {1}".format(path1[len(common):], path2[len(common):]) | |
def convert_one(scaler, srcname, dstname): | |
pixelsAsList = None | |
w = None | |
try: | |
srcfile = open(srcname, 'r') | |
except IOError as x: | |
print x | |
exit(1) | |
with srcfile: | |
r=png.Reader(srcfile) | |
width, height, pixels, metadata = r.read() | |
pixelsAsList = list(pixels) | |
if not pixelsAsList: | |
print "Error decoding the image" | |
exit(1) | |
print "{0}: {1}x{2} -> {3}".format(os.path.basename(srcname), width, height, os.path.basename(dstname)) | |
#print metadata | |
if metadata['bitdepth'] == 8 and metadata['planes'] == 4 and metadata['alpha']: | |
for row in pixelsAsList: | |
for offset in xrange(3, width * 4, 4): | |
row[offset] = scaler.apply(row[offset]) | |
w = png.Writer(width=width, height=height, bitdepth=8, alpha=True) | |
elif metadata['bitdepth'] == 8 and metadata['planes'] == 2 and metadata['alpha']: | |
for row in pixelsAsList: | |
for offset in xrange(1, width * 2, 2): | |
row[offset] = scaler.apply(row[offset]) | |
w = png.Writer(width=width, height=height, bitdepth=8, greyscale=True, alpha=True) | |
if w: | |
try: | |
dstfile = open(dstname, 'w') | |
except IOError as x: | |
print x | |
exit(1) | |
with dstfile: | |
w.write(dstfile, pixelsAsList) | |
def convert_xdens(scaler, srcname, dstname): | |
# Do the specified pair | |
convert_one(scaler, srcname, dstname) | |
# Find the rest | |
srcbase = os.path.dirname(os.path.dirname(os.path.abspath(srcname))) | |
dstbase = os.path.dirname(os.path.dirname(os.path.abspath(dstname))) | |
for srcnm in os.listdir(srcbase): | |
srcdir = os.path.join(srcbase, srcnm) | |
if os.path.isdir(srcdir): | |
if srcnm.startswith('drawable-'): | |
dstnm = MAPPING.get(srcnm, srcnm) | |
dstdir = os.path.join(dstbase, dstnm) | |
if os.path.exists(dstdir) and os.path.isdir(dstdir): | |
src1 = os.path.join(srcdir, os.path.basename(srcname)) | |
dst1 = os.path.join(dstdir, os.path.basename(dstname)) | |
if os.path.exists(src1) and not os.path.samefile(srcname, src1): | |
print "\nDirectory {0}".format(shorten_path_pair(srcdir, dstdir)) | |
convert_one(scaler, src1, dst1) | |
def convert_dir(scaler, dirname): | |
dirprinted = False | |
for nm in os.listdir(dirname): | |
nmf = os.path.join(dirname, nm) | |
if os.path.isdir(nmf): | |
if nm.startswith('drawable-'): | |
convert_dir(scaler, nmf) | |
else: | |
m = re.match('(?:bb_)?ic_menu_[a-zA-Z_]+_holo_dark\\.png', nm) | |
if m != None: | |
if not dirprinted: | |
print "\n>> {0}".format(dirname) | |
dirprinted = True | |
mt = nm.replace("_holo_dark", "_material") | |
convert_one(scaler, nmf, os.path.join(dirname, mt)) | |
if __name__ == "__main__": | |
''' | |
Parse command line arguments | |
''' | |
parser = argparse.ArgumentParser(description='Scales alpha values of png images') | |
parser.add_argument('-s', dest='scale', required=True, help='scale value (percent)') | |
parser.add_argument('-d', dest='dir', required=False, help='convert all files under directory') | |
parser.add_argument('-x', dest='xdens', action='store_true', required=False, help='automatically apply to resources under other desnities') | |
parser.add_argument('src', nargs='?', help='source file') | |
parser.add_argument('dst', nargs='?', help='destination file') | |
args = parser.parse_args() | |
scale = 100 | |
try: | |
scale = int(args.scale) | |
except ValueError as x: | |
print x | |
exit(1) | |
scaler = Scaler(args.scale) | |
if args.dir: | |
if args.src or args.dst: | |
print "Source and destination files should not be there" | |
exit(1) | |
convert_dir(scaler, args.dir) | |
pass | |
else: | |
if not args.src or not args.dst: | |
print "Source and destination files are required" | |
exit(1) | |
if args.xdens: | |
print "Scaling all densities" | |
convert_xdens(scaler, args.src, args.dst) | |
else: | |
convert_one(scaler, args.src, args.dst) | |
pass |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment