Advertisement
Guest User

Android Downsampler

a guest
Mar 26th, 2015
590
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.31 KB | None | 0 0
  1. #!/usr/bin/env python
  2. from PIL import Image as PilImage
  3. import sys, os.path, ConfigParser
  4. from Tkinter import *
  5. import ttk
  6. import tkFileDialog, tkMessageBox
  7. import codecs
  8.  
  9. # Fix for Unicode Filenames ( http://habrahabr.ru/post/119405/ )
  10. class UnicodeConfigParser(ConfigParser.RawConfigParser):
  11.  
  12.     def __init__(self, *args, **kwargs):
  13.         ConfigParser.RawConfigParser.__init__(self, *args, **kwargs)
  14.  
  15.     def write(self, fp):
  16.         """Fixed for Unicode output"""
  17.         if self._defaults:
  18.             fp.write("[%s]\n" % DEFAULTSECT)
  19.             for (key, value) in self._defaults.items():
  20.                 fp.write("%s = %s\n" % (key, unicode(value).replace('\n', '\n\t')))
  21.             fp.write("\n")
  22.         for section in self._sections:
  23.             fp.write("[%s]\n" % section)
  24.             for (key, value) in self._sections[section].items():
  25.                 if key != "__name__":
  26.                     fp.write("%s = %s\n" %
  27.                              (key, unicode(value).replace('\n','\n\t')))
  28.             fp.write("\n")
  29.  
  30.     # This function is needed to override default lower-case conversion
  31.     # of the parameter's names. They will be saved 'as is'.
  32.     def optionxform(self, strOut):
  33.         return strOut
  34.  
  35. resolutions = [("mdpi", 1.0), ("hdpi", 1.5), ("xhdpi", 2.0), ("xxhdpi", 3.0), ("xxxhdpi", 4.0)]
  36. configFile = "config.txt"
  37. configSection = "configuration"
  38. configLastDir = "LastDir"
  39.  
  40. imagePath = u""
  41. imageDir = u""
  42. imageName = u""
  43. image = None
  44. defWidth = defHeight = 1
  45.  
  46. root = Tk()
  47. root.title("Android Drawable Downsampler")
  48. root.resizable(0, 0)
  49. pyfilepath = ""
  50. if hasattr(sys, 'frozen'):
  51.     pyfilepath = sys.executable
  52. else:
  53.     pyfilepath = os.path.realpath(__file__)
  54. pyfilepath = os.path.dirname(pyfilepath)
  55. iconpath = pyfilepath + "/addownsampler.ico"
  56. if os.path.exists(iconpath):
  57.     root.iconbitmap(iconpath)
  58. widthVar = StringVar()
  59. heightVar = StringVar()
  60. labelFileName = convertButton = buttonCalculateSizes = None
  61.  
  62. configdir = os.path.expanduser("~") + "/.downsampler/"
  63. if not os.path.exists(configdir):
  64.     os.makedirs(configdir)
  65. configpath = configdir + configFile
  66.  
  67. def loadParameter(param, defval):
  68.     if os.path.exists(configpath):
  69.         parser = ConfigParser.ConfigParser()
  70.         parser.optionxform = unicode
  71.         parser.readfp(codecs.open(configpath, "rb", "utf8"))
  72.         items = parser.items(configSection)
  73.         itemsDict = dict(items)
  74.         return itemsDict[param]
  75.     else:
  76.         return defval
  77.  
  78. def storeParameter(param, value):
  79.     parser = UnicodeConfigParser()
  80.     if os.path.exists(configpath):
  81.         parser.read(configpath)
  82.     else:
  83.         parser.add_section(configSection)
  84.     parser.set(configSection, param, value)
  85.     with codecs.open(configpath, "wb", "utf8") as cfile:
  86.         parser.write(cfile)
  87.  
  88. def onSelectFile():
  89.     global imagePath, imageDir, imageName, image, defHeight, defWidth
  90.     options = dict()
  91.     options['initialdir'] = loadParameter(configLastDir, pyfilepath)
  92.     options['title'] = 'Select original large image'
  93.     options['filetypes'] = [('PNG files', '.png')]
  94.     imagePath = tkFileDialog.askopenfilename(**options)
  95.  
  96.     if len(imagePath) == 0:
  97.         return
  98.  
  99.     imageDir = os.path.dirname(imagePath)
  100.     storeParameter(configLastDir, imageDir)
  101.     imageName = os.path.basename(imagePath)
  102.  
  103.     image = PilImage.open(imagePath)
  104.     defWidth, defHeight = image.size
  105.  
  106.     labelFileName["text"] = imageName + " (%dx%d)" % (defWidth, defHeight)
  107.     convertButton["state"] = "enabled"
  108.     buttonCalculateSizes["state"] = "enabled"
  109.  
  110. def calculateSizes():
  111.     if len(widthVar.get()) == 0 and len(heightVar.get()) > 0:
  112.         height = int(heightVar.get())
  113.         width = int(1.0 * defWidth / defHeight * height)
  114.         widthVar.set(str(width))
  115.     if len(widthVar.get()) > 0 and len(heightVar.get()) == 0:
  116.         width = int(widthVar.get())
  117.         height = int(1.0 * defHeight / defWidth * width)
  118.         heightVar.set(str(height))
  119.  
  120. def convert():
  121.     if len(widthVar.get()) == 0 or len(heightVar.get()) == 0:
  122.         tkMessageBox.showinfo("Error", "Please, specify width and height for MDPI resolution")
  123.         return
  124.     convertButton["state"] = "disabled"
  125.  
  126.     width = int(widthVar.get())
  127.     height = int(heightVar.get())
  128.     sizes = {resolution[0]: (int(width * resolution[1]), int(height * resolution[1])) for resolution in resolutions}
  129.  
  130.     for category, (width, height) in sizes.iteritems():
  131.         finaldir = imageDir + "/drawable-" + category
  132.         if not os.path.exists(finaldir):
  133.             os.makedirs(finaldir)
  134.         print("Resizing for %s to %dx%d" % (category, width, height))
  135.         imageResized = image.resize((width, height), PilImage.ANTIALIAS)
  136.         imageResized.save(finaldir + "/" + imageName)
  137.  
  138.     convertButton["state"] = "enabled"
  139.  
  140. labelFileName = ttk.Label(root, text = "Please, select original image")
  141. labelFileName.grid(row = 0, column = 0, columnspan = 2)
  142.  
  143. buttonSelectFile = ttk.Button(root, text="Choose file...", width = 40, command = onSelectFile)
  144. buttonSelectFile.grid(row = 1, column = 0, columnspan = 2)
  145.  
  146. ttk.Label(root, text = "MDPI Width").grid(row = 2, column = 0)
  147. ttk.Label(root, text = "MDPI Height").grid(row = 2, column = 1)
  148.  
  149. textWidth = ttk.Entry(root, width = 30, textvariable = widthVar, justify = "center")
  150. textWidth.grid(row = 3, column = 0)
  151. textHeight = ttk.Entry(root, width = 30, textvariable = heightVar, justify = "center")
  152. textHeight.grid(row = 3, column = 1)
  153.  
  154. buttonCalculateSizes = ttk.Button(root, text = "Width <==> Height", width = 40, command = calculateSizes)
  155. buttonCalculateSizes.grid(row = 4, column = 0, columnspan = 2)
  156. buttonCalculateSizes["state"] = "disabled"
  157.  
  158. ttk.Label(root,
  159.     text = "If you left width OR height empty, press button above to maintain aspect ratio").\
  160.     grid(row = 5, column = 0, columnspan = 2)
  161.  
  162. convertButton = ttk.Button(root, text = "_____  DO  IT  _____", width = 40, command = convert)
  163. convertButton.grid(row = 6, column = 0, columnspan = 2)
  164. convertButton["state"] = "disabled"
  165.  
  166. ttk.Label(root,
  167.     text = "Result files will be placed to appropriate folders in original image directory").\
  168.     grid(row = 7, column = 0, columnspan = 2)
  169.  
  170. ttk.Label(root,
  171.     text = "Version 0.1 by Egor Aristov (ef@efprojects.com)").\
  172.     grid(row = 8, column = 0, columnspan = 2)
  173.  
  174. root.mainloop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement