Skip to content

Instantly share code, notes, and snippets.

@kmansoft
Created July 19, 2015 18:57
Show Gist options
  • Save kmansoft/b206c1f4d7ac9e4601fc to your computer and use it in GitHub Desktop.
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%).
#!/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