I have several images that I'm trying to use GIMP Python-Fu to process. What I am trying to do is:
- open a *.png with transparency
- create a new layer that is transparent and inject it below the existing image
- copy the contents of my original layer and paste them into the new one
- desaturate the copy and set its lightness to 0
- Desired effect: get a 100% black effect of the original image, to be a shadow
- Hue-Chroma was my manual approach, but that appears to be missing from GIMP's Procedures
- adjust the background shadow layer so that it is offset by an X and Y amount
- Set the alpha/opacity for the shadow to be 50% transparent
- render these layers
- Persist to a new location
I think that I have the general gist down, but I am stuck with new layers, even those created as RGBA, always having the background color currently set in GIMP. When I flatten these two layers, the resultant *.PNG is filled with the background color rather than transparency that I would expect given the corresponding behaviors from the GIMP UI.
Here is what I have:
import os, glob, sys, time
from gimpfu import *
import gimpcolor
def ie_inventory_shadow(file, x_offset, y_offset, outputFolder):
#Open the file; size to 64x64; duplicate layer; make black; offset 4, 5; set opacity to 50%; save to output
print "Opening '" + file + "' ..."
# Indicates that the process has started.
gimp.progress_init("Opening '" + file + "' ...")
try:
filename = os.path.basename(file)
# Use slicing to remove the extension
filename_without_ext = filename[:filename.rindex('.')]
# Open file.
fileImage = None
fileImage = pdb.gimp_file_load(file, file, run_mode=RUN_NONINTERACTIVE)
print "Opened '" + filename_without_ext + "' ..."
#resize
pdb.gimp_context_set_interpolation(2) #INTERPOLATION-CUBIC (2)
pdb.gimp_image_scale(fileImage, 64, 64)
layer = fileImage.layers[0]
print "Resized '" + filename_without_ext + "' ..."
# Create new layer.
pdb.gimp_context_set_background((0,255,0))
#newLayer = pdb.gimp_layer_new(fileImage, layer.width, layer.height, RGBA_IMAGE, "Shadow", layer.opacity, layer.mode) #RGBA-IMAGE (1)
#pdb.gimp_layer_add_alpha(newLayer)
#pdb.gimp_drawable_fill(newLayer, 3) #FILL-TRANSPARENT (3)
pdb.gimp_layer_new_from_visible(fileImage, fileImage, "shadow")
print "Created New Layer for '" + filename_without_ext + "' ..."
pdb.gimp_image_insert_layer(fileImage, newLayer, None, +1) # the +1 adds it behind the top layer
#pdb.gimp_edit_clear(newLayer)
##### Fuck my life. The new layer ALWAYS has the background color. But I simply CANNOT figure out how to make this motherfucker transparent.
print "Inserted New Layer for '" + filename_without_ext + "' ..."
# Put image into the new layer.
pdb.gimp_edit_copy(layer)
floating = pdb.gimp_edit_paste(newLayer, True)
# Update the new layer.
newLayer.flush()
newLayer.merge_shadow(True)
newLayer.update(0, 0, newLayer.width, newLayer.height)
# floating to layer
pdb.gimp_floating_sel_to_layer(floating)
print "Duplicated '" + filename_without_ext + "' ..."
#make layer black
pdb.gimp_brightness_contrast(newLayer, -127, 127)
print "Shadowed '" + filename_without_ext + "' ..."
#move the layer
pdb.gimp_layer_set_offsets(newLayer, x_offset, y_offset)
print "Moved '" + filename_without_ext + "' ..."
#set opacity
pdb.gimp_layer_set_opacity(newLayer, 50)
print "Set Opacity on '" + filename_without_ext + "' ..."
#flatten
flattened = pdb.gimp_image_flatten(fileImage)
print "Flattened '" + filename_without_ext + "' ..."
# Export flattened image
target = outputFolder + "/" + filename_without_ext + "-s.png"
print "Saving '" + target + "' ..."
pdb.file_png_save_defaults(fileImage, flattened, target, target, run_mode=RUN_NONINTERACTIVE)
#pdb.file_png_save2(fileImage, flattened, target, target, False, 9, True, False, False, True, True, False, False, run_mode=RUN_NONINTERACTIVE)
print "Saved '" + target + "'!"
except Exception as err:
gimp.message("Unexpected error: " + str(err))
def run(directory, x_offset, y_offset, outputFolder):
print "Run: directory : %s" % directory
print "Run: outputFolder : %s" % outputFolder
print "Run: x_offset : %s" % x_offset
print "Run: y_offset : %s" % y_offset
start=time.time()
print "Run: Running on directory \"%s\"" % directory
globPath = os.path.join(directory, '*.png')
print "looking at path: %s" % globPath
for infile in glob.glob(globPath):
print "Run: found file : %s" % infile
ie_inventory_shadow(infile, x_offset, y_offset, outputFolder)
end=time.time()
print "Finished, total processing time: %.2f seconds" % (end-start)
if __name__ == "__main__":
print "Running as __main__ with args: %s" % sys.argv
I spend 2 days banging my head against this problem, and found it just minutes after posting...
The problem was the flatten call. The documentation states that flatten will remove the alpha channel:
The solution was to instead use
gimp_image_merge_visible_layers
: