#!/usr/bin/python # /File/Export/Synfig # exports gimp document to synfig's canvas and png images # if output is omited then script saves image to same dir # with source image ## # Author: IL'dar AKHmetgaleev aka AkhIL # e-mail: akhilman at gmail dot com # web: http://akhilman.blogspot.com # # This code is licensed under # Creative Commons Attribution 3.0 Unported License # http://creativecommons.org/licenses/by/3.0/ ## # # History: # 2008-01-31 first public release # 2008-04-26 gimp-2.2 compatibility fix by dooglus # 2008-08-18 now works without alpha channel # from gimpfu import * import os import gzip documentbegin = """\ %(name)s """ documentend = """\ """ inlinebegin = """\ %(x)f %(y)f """ inlineend = """\ """ imagelayer = """\ -%(x)f %(y)f %(x)f -%(y)f %(file)s """ zoomlayer = """ 0.0000000000 0.0000000000 """ rotatelayer = """ 0.0000000000 0.0000000000 """ translatelayer = """ 0.0000000000 0.0000000000 """ # from synfig-core/src/synfig/color.h BLEND_COMPOSITE=0 BLEND_STRAIGHT=1 BLEND_ONTO=13 BLEND_STRAIGHT_ONTO=21 BLEND_BEHIND=12 BLEND_SCREEN=16 BLEND_OVERLAY=20 BLEND_HARD_LIGHT=17 BLEND_MULTIPLY=6 BLEND_DIVIDE=7 BLEND_ADD=4 BLEND_SUBTRACT=5 BLEND_DIFFERENCE=18 BLEND_BRIGHTEN=2 BLEND_DARKEN=3 BLEND_COLOR=8 BLEND_HUE=9 BLEND_SATURATION=10 BLEND_LUMINANCE=11 BLEND_ALPHA_BRIGHTEN=14 BLEND_ALPHA_DARKEN=15 BLEND_ALPHA_OVER=19 def gimp2synfig_mode_converter(mode): """ converts gimp's layer compositning mode to synfig's blend method """ modes = { NORMAL_MODE : BLEND_COMPOSITE, DISSOLVE_MODE : BLEND_COMPOSITE, BEHIND_MODE : BLEND_BEHIND, MULTIPLY_MODE : BLEND_MULTIPLY, SCREEN_MODE : BLEND_SCREEN, OVERLAY_MODE : BLEND_OVERLAY, DIFFERENCE_MODE : BLEND_DIFFERENCE, ADDITION_MODE : BLEND_ADD, SUBTRACT_MODE : BLEND_SUBTRACT, DARKEN_ONLY_MODE : BLEND_DARKEN, LIGHTEN_ONLY_MODE : BLEND_BRIGHTEN, HUE_MODE : BLEND_HUE, SATURATION_MODE : BLEND_SATURATION, COLOR_MODE : BLEND_COLOR, VALUE_MODE : BLEND_LUMINANCE, DIVIDE_MODE : BLEND_DIVIDE, DODGE_MODE : BLEND_BRIGHTEN, BURN_MODE : BLEND_MULTIPLY, HARDLIGHT_MODE : BLEND_HARD_LIGHT, SOFTLIGHT_MODE : BLEND_COMPOSITE, GRAIN_EXTRACT_MODE: BLEND_COMPOSITE, GRAIN_MERGE_MODE : BLEND_COMPOSITE, COLOR_ERASE_MODE : BLEND_COMPOSITE, } return modes[mode] def python_fu_exportsynfig(img,layer, output, span, doinvisible, applymask, dozoom, dorot, dotrans): if output: prefix = os.path.splitext(output)[0] suffix = os.path.splitext(output)[1] suffix = "sifz" else: prefix = img.filename.split('.xcf')[0] suffix = "sifz" name = os.path.basename(prefix) prefix = os.path.dirname(prefix) layersprefix = os.path.join(prefix,"%s_layers"%name) if not os.path.isdir(layersprefix): os.makedirs(layersprefix) # make path for layers siffile = gzip.open("%s.%s"%(os.path.join(prefix,name), suffix),"w") pixelsize = 1/(img.width**2 + img.height**2)**0.5*span siffile.write(documentbegin %{ \ "width":img.width, \ "height":img.height, \ "xres":pdb.gimp_image_get_resolution(img)[0]*39.37007904, \ "yres":pdb.gimp_image_get_resolution(img)[1]*39.37007904, \ "x":img.width*pixelsize/2, \ "y":img.height*pixelsize/2, \ "name":img.name \ }) # aplying layer masks if applymask: img = img.duplicate() for l in img.layers: if not l.visible and not doinvisible: continue # don't process invisible if pdb.gimp_layer_get_mask(l): pdb.gimp_layer_remove_mask(l, 0) # exporting layers totallayers = len(img.layers) donelayers = 0 for l in reversed(img.layers): if not l.visible: if not doinvisible: continue # don't process invisible else: active = 'false' else: active = 'true' siffile.write(inlinebegin % {\ "name":l.name, \ "amount":l.opacity*0.01, \ "active":active, \ "blend_method":gimp2synfig_mode_converter(l.mode), \ "x":(l.width/2.0+pdb.gimp_drawable_offsets(l)[0]-img.width/2.0)*pixelsize, \ "y":(l.height/2.0+pdb.gimp_drawable_offsets(l)[1]-img.height/2.0)*pixelsize*-1 \ }) # maknig file names filename = "%s.png" % ( \ l.name.replace(" ","_").replace('#',"_",) \ ) maskname = "%s_mask.png" % ( \ l.name.replace(" ","_").replace("#","_") \ ) # exporting layer newimg = gimp.Image(l.width,l.height,img.base_type) pdb.gimp_edit_copy(l) newlayer = gimp.Layer(newimg, l.name, l.width, l.height, l.type, 1, NORMAL_MODE) pdb.gimp_drawable_fill(newlayer, TRANSPARENT_FILL) newimg.add_layer(newlayer) pdb.gimp_floating_sel_anchor(pdb.gimp_edit_paste(newlayer, True)) pdb.gimp_file_save(newimg, newlayer, os.path.join(layersprefix,filename), filename) pdb.gimp_image_delete(newimg) siffile.write(imagelayer % {\ "name":filename, \ "file":os.path.join("%s_layers"%name,filename), \ "blend_method":BLEND_COMPOSITE, \ "amount":1.0, \ "x":l.width/2*pixelsize, \ "y":l.height/2*pixelsize \ }) # exporting layer mask if pdb.gimp_layer_get_mask(l): newimg = gimp.Image(l.width,l.height,GRAY) pdb.gimp_edit_copy(pdb.gimp_layer_get_mask(l)) newlayer = gimp.Layer(newimg, l.name, l.width, l.height, GRAYA_IMAGE) pdb.gimp_drawable_fill(newlayer, TRANSPARENT_FILL) newimg.add_layer(newlayer) pdb.gimp_floating_sel_anchor(pdb.gimp_edit_paste(newlayer, True)) pdb.gimp_invert(newlayer) mask = pdb.gimp_layer_create_mask(newlayer,ADD_COPY_MASK) pdb.gimp_image_add_layer_mask(newimg,newlayer,mask) pdb.gimp_layer_remove_mask(newlayer, 0) pdb.gimp_file_save(newimg, newlayer, os.path.join(layersprefix,maskname), filename) pdb.gimp_image_delete(newimg) siffile.write(imagelayer % {\ "name":maskname, \ "file":os.path.join("%s_layers"%name,maskname), \ "blend_method":BLEND_ALPHA_OVER, \ "amount":1.0, \ "x":l.width/2*pixelsize, \ "y":l.height/2*pixelsize \ }) # adding transform layers if dozoom: siffile.write(zoomlayer%{"name":"%s_scale"%l.name}) if dorot: siffile.write(rotatelayer%{"name":"%s_rot"%l.name}) if dotrans: siffile.write(translatelayer%{"name":"%s_loc"%l.name}) siffile.write(inlineend) donelayers += 1 if applymask: pdb.gimp_image_delete(img) siffile.write(documentend) siffile.close() register( "python_fu_exportsynfig", "Export document to synfig's format", "Export document to synfig's format\nBy default saves to same dir as source image", "AkhIL", "AkhIL", "2008-08-18", "/File/E_xport/_Synfig", "RGB*, GRAY*", [ (PF_STRING, "output", "output path (optional)", ""), (PF_FLOAT, "span", "Image Span",9.1788), (PF_BOOL, "doinvisible", "Export invisible layers",True), (PF_BOOL, "applymask", "Apply layer masks",False), (PF_BOOL, "dozoom", "Add zoom layers",False), (PF_BOOL, "dorot", "Add rotate layers",False), (PF_BOOL, "dotrans", "Add translate layers",False) ], [], python_fu_exportsynfig) main()