__init__.py 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. import os
  2. import random
  3. import threading
  4. from gi.repository import GLib
  5. import cv2
  6. import subprocess
  7. class ExportDialog:
  8. def __init__(self, root, builder, w, h, get_image_call, done_call, path):
  9. self.path = path
  10. self.builder = builder
  11. self.root = root
  12. # What gets called to get the image object at process time
  13. self.get_image_call = get_image_call
  14. self.done_call = done_call
  15. self.width = w
  16. self.height = h
  17. self.image = None
  18. UI_FILE = "ui/Export.glade"
  19. self.builder.add_from_file(UI_FILE)
  20. self.ui = {}
  21. components = [
  22. "window",
  23. "headerbar",
  24. "file",
  25. "save_button",
  26. "cancel_button",
  27. "preset",
  28. "format",
  29. "pngcrush",
  30. "width",
  31. "height",
  32. "quality",
  33. "width_spin",
  34. "height_spin",
  35. "quality_spin"
  36. ]
  37. for component in components:
  38. self.ui[component] = self.builder.get_object("Export_%s" % (component))
  39. # Setup Export Dialog
  40. self.ui["window"].set_transient_for(self.root)
  41. self.ui["window"].set_titlebar(self.ui["headerbar"])
  42. self.ui["width"].set_upper(w)
  43. self.ui["width"].set_value(w)
  44. self.ui["height"].set_upper(h)
  45. self.ui["height"].set_value(h)
  46. self.ui["file"].set_filename(".".join(path.split(".")[:-1]) + "_PF")
  47. self.ui["file"].set_current_name(".".join(path.split("/")[-1:][0].split(".")[:-1]) + "_PF")
  48. # Connect siginals
  49. self.ui["preset"].connect("changed", self.on_preset_changed)
  50. self.ui["format"].connect("changed", self.on_format_changed)
  51. self.ui["width_spin"].connect("changed", self.on_width_changed)
  52. self.ui["height_spin"].connect("changed", self.on_height_changed)
  53. self.ui["save_button"].connect("clicked", self.on_save_clicked)
  54. self.ui["cancel_button"].connect("clicked", self.on_cancel_clicked)
  55. self.ui["window"].show_all()
  56. def on_preset_changed(self, sender):
  57. if(sender.get_active() == 0):
  58. self.ui["width_spin"].set_sensitive(True)
  59. self.ui["height_spin"].set_sensitive(True)
  60. self.ui["format"].set_sensitive(True)
  61. self.ui["pngcrush"].set_sensitive(self.ui["format"].get_active() == 0)
  62. self.ui["quality_spin"].set_sensitive(self.ui["format"].get_active() == 1)
  63. else:
  64. if(sender.get_active() == 1):
  65. self.ui["width"].set_value(2048)
  66. self.ui["format"].set_active(1)
  67. self.ui["quality"].set_value(85)
  68. elif(sender.get_active() == 2):
  69. self.ui["width"].set_value(self.width)
  70. self.ui["format"].set_active(0)
  71. self.ui["pngcrush"].set_active(True)
  72. elif(sender.get_active() == 3):
  73. self.ui["width"].set_value(1920)
  74. self.ui["format"].set_active(1)
  75. self.ui["quality"].set_value(67)
  76. elif(sender.get_active() == 4):
  77. self.ui["width"].set_value(self.width)
  78. self.ui["format"].set_active(2)
  79. self.ui["width_spin"].set_sensitive(False)
  80. self.ui["height_spin"].set_sensitive(False)
  81. self.ui["format"].set_sensitive(False)
  82. self.ui["pngcrush"].set_sensitive(False)
  83. self.ui["quality_spin"].set_sensitive(False)
  84. def on_format_changed(self, sender):
  85. self.ui["pngcrush"].set_sensitive(sender.get_active() == 0)
  86. self.ui["quality_spin"].set_sensitive(sender.get_active() == 1)
  87. self.ui["pngcrush"].set_active(False)
  88. def on_width_changed(self, sender):
  89. w = sender.get_value()
  90. r = w/self.width
  91. self.ui["height_spin"].set_value(r*self.height)
  92. def on_height_changed(self, sender):
  93. h = sender.get_value()
  94. r = h/self.height
  95. self.ui["width_spin"].set_value(r*self.width)
  96. def on_cancel_clicked(self, sender):
  97. self.ui["window"].close()
  98. def on_save_clicked(self, sender):
  99. self.ui["window"].close()
  100. format = self.ui["format"].get_active()
  101. quality = self.ui["quality"].get_value()
  102. width = self.ui["width"].get_value()
  103. height = self.ui["height"].get_value()
  104. path = self.ui["file"].get_filename()
  105. pngcrush = self.ui["pngcrush"].get_active()
  106. threading.Thread(target=self.do_export, args=(format, quality, width,
  107. height, path, pngcrush)).start()
  108. def do_export(self, format, quality, width, height, path, pngcrush):
  109. self.image = self.get_image_call(width, height)
  110. newPath = path
  111. if(format == 0) and (not path.endswith(".png")):
  112. newPath += ".png"
  113. if(format == 1) and (not path.endswith(".jpg")) and (not path.endswith(".jpeg")):
  114. newPath += ".jpg"
  115. if(format == 2) and (not path.endswith(".tif")) and (not path.endswith(".tiff")):
  116. newPath += ".tiff"
  117. if(format == 1):
  118. # Convert to 8 Bit
  119. bpp = int(str(self.image.dtype).replace("uint", ""))
  120. im = (self.image/float(2**bpp))*255
  121. cv2.imwrite(newPath, im, [int(cv2.IMWRITE_JPEG_QUALITY), int(quality)])
  122. elif(format == 0) and pngcrush:
  123. tempPath = "/tmp/pngcrush-%i.png" % random.randrange(1000000,9999999)
  124. cv2.imwrite(tempPath, self.image)
  125. subprocess.call(["pngcrush", "-rem gAMA", "-rem cHRM", "-rem iCCP", "-rem sRGB" , "-m 0", "-l 9", "-fix", "-v", "-v", tempPath, newPath])
  126. else:
  127. cv2.imwrite(newPath, self.image)
  128. GLib.idle_add(self.done_call, newPath)