Skip to content

Instantly share code, notes, and snippets.

@zeffii
Forked from anonymous/image_editor_flatten.py
Last active August 29, 2015 14:23
Show Gist options
  • Save zeffii/eff101fca227ac706d9b to your computer and use it in GitHub Desktop.
Save zeffii/eff101fca227ac706d9b to your computer and use it in GitHub Desktop.
# ***** BEGIN GPL LICENSE BLOCK *****
#
# This program is free software; you may redistribute it, and/or
# modify it, under the terms of the GNU General Public License
# as published by the Free Software Foundation - either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, write to:
#
# the Free Software Foundation Inc.
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301, USA
#
# or go online at: http://www.gnu.org/licenses/ to view license options.
#
# Author Dealga McArdle 2015
#
# ***** END GPL LICENCE BLOCK *****
bl_info = {
"name": "Merge Flatten selected images",
"author": "Dealga McArdle",
"version": (0, 0, 1),
"blender": (2, 7, 5),
"location": "Image Editor (right side panel)",
"description": "Adds composite panel in Image Editor",
"wiki_url": "",
"tracker_url": "",
"category": "UV/Image Editor"}
import os
import os
import sys
import subprocess
import threading
import bpy
from bpy.props import StringProperty, EnumProperty
from bpy_extras.io_utils import ExportHelper
class TKD_Controller_Thread(threading.Thread):
def __init__(self, commands, basedir, caller):
self.commands = commands.split()
self.basedir = basedir
self.caller = caller
threading.Thread.__init__(self)
def run(self):
initial_location = os.getcwd()
try:
os.chdir(self.basedir)
print("starting controlled thread")
''' not waiting
subprocess.Popen(self.commands.split())
'''
subprocess.call(self.commands)
filepath = os.path.join(self.basedir, self.commands[-1])
print('load:', filepath)
if os.path.exists(filepath):
bpy.data.images.load(filepath)
else:
print("didn't exist yet")
except:
self.caller.report({'WARNING'}, 'check console for imagemagick output')
print("finished thread")
bpy.context.scene.TKD_composite_image_name = ""
os.chdir(initial_location)
class TKD_Callback_Operator(bpy.types.Operator):
bl_idname = "image.tkd_callback_operator"
bl_label = "TKD image merger callback"
bl_options = {'REGISTER', 'UNDO'}
fn_name = StringProperty(default='')
def execute(self, context):
scn = context.scene
fn_name = self.fn_name
if fn_name == "merge and load":
output_name = scn.TKD_composite_image_name
if not output_name:
self.report({'WARNING'}, 'must give an outputname')
else:
command = "convert {0} {1} -flatten {2}"
a = scn.TKD_base_image_name
b = scn.TKD_overlay_image_name
c = output_name
if not any([c.endswith(a) for a in ['.png', '.jpg', '.tiff']]):
c = output_name + '.png'
command = command.format(a, b, c)
th = TKD_Controller_Thread(command, basedir=scn.TKD_base_path_name, caller=self)
th.start()
return {'FINISHED'}
class TKD_DirectorySelectorOperator(bpy.types.Operator, ExportHelper):
bl_idname = "image.tkd_folder_selector"
bl_label = "image folder"
filename_ext = "."
use_filter_folder = True
def execute(self, context):
# even if you pick a file i'll strip it and get the dirname
fdir = self.properties.filepath
dp = os.path.dirname(fdir)
context.scene.TKD_base_path_name = dp
return{'FINISHED'}
class TKD_image_composite(bpy.types.Panel):
"""Creates a Panel in the Object properties window"""
bl_label = "Overlay Images"
bl_idname = "IMAGE_PT_overlay"
bl_space_type = 'IMAGE_EDITOR'
bl_region_type = 'UI'
def draw(self, context):
layout = self.layout
layout.row().label(text="by folder")
row = layout.row(align=True)
row.prop(context.scene, "TKD_base_path_name", text="")
row.operator("image.tkd_folder_selector", icon="FILE_FOLDER", text="")
if not context.scene.TKD_base_path_name:
return
col = layout.column()
col.label(text="base image")
col.prop(context.scene, "TKD_base_image_name", text="")
col.label(text="region to add")
col.prop(context.scene, "TKD_overlay_image_name", text="")
col.label(text="give it a name (auto-postfix .png)")
col.prop(context.scene, "TKD_composite_image_name", text="")
op = col.operator("image.tkd_callback_operator", text="Merge and load")
op.fn_name = "merge and load"
scn = bpy.types.Scene
def register():
scn.TKD_base_path_name = StringProperty()
scn.TKD_composite_image_name = StringProperty()
def avail_images(self, context):
img_path = context.scene.TKD_base_path_name
if not img_path:
return [("", "", "")]
items = [(t, t, "") for t in next(os.walk(img_path))[2] if t.endswith('png')]
return items
scn.TKD_base_image_name = EnumProperty(
items=avail_images,
name='base_image_files',
description='choose file to load as base file')
scn.TKD_overlay_image_name = EnumProperty(
items=avail_images,
name='overlay_image_files',
description='choose file to load as overlay file')
bpy.utils.register_class(TKD_Callback_Operator)
bpy.utils.register_class(TKD_DirectorySelectorOperator)
bpy.utils.register_class(TKD_image_composite)
def unregister():
bpy.utils.unregister_class(TKD_image_composite)
bpy.utils.unregister_class(TKD_DirectorySelectorOperator)
bpy.utils.unregister_class(TKD_Callback_Operator)
del scn.TKD_base_image_name
del scn.TKD_overlay_image_name
del scn.TKD_composite_image_name
del scn.TKD_base_path_name
if __name__ == "__main__":
register()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment