Skip to content

Instantly share code, notes, and snippets.

@xenogenesi
Last active August 16, 2017 15:50
Show Gist options
  • Save xenogenesi/df729bd760429a01cd53849fe9b9867d to your computer and use it in GitHub Desktop.
Save xenogenesi/df729bd760429a01cd53849fe9b9867d to your computer and use it in GitHub Desktop.
gimp py fu console script: from an image with multiple layers, cut and save each layer by transparency saving the coordinates into a json file
# from gimp py fu console
# execfile("/path/to/this-script.py")
# for each layer use magic wand at pixel 1,1 (assume it is transparent), and create a selection, inverse it, transform to rectangle bounding box
# copy it and paste into a new image, save as png (and save the original coordinates into a json { "layer-name": [ x1, y1, x2, y2 ] }
from array import array
savepath="/tmp/slices/"
f = open("{0}images.json".format(savepath), "w")
print >> f, "window.images = {"
# Final Color = (Source Color x alpha /255) + [Background Color x (255-alpha)/255]
bg_color = array("B", [0, 0, 0x80])
def alpha_blend(fg, bg, alpha):
r = (fg[0] * alpha / 255) + (bg[0] * (255 - alpha) / 255)
g = (fg[1] * alpha / 255) + (bg[1] * (255 - alpha) / 255)
b = (fg[2] * alpha / 255) + (bg[2] * (255 - alpha) / 255)
return array("B", [r, g, b, 255])
# reference for accessing region pixels
# http://shallowsky.com/software/arclayer/arclayer-0.3.py
def process_alpha(layer):
width, height = layer.width, layer.height
rgn = layer.get_pixel_rgn(0, 0, width, height, True, False)
# p_size assumed to be 4 bytes (r,g,b,a)
p_size = len(rgn[0,0])
pixels = array("B", rgn[0:width, 0:height])
for x in xrange(0, width):
for y in xrange(0, height):
pos = ((width * y) + x) * p_size
src_pixel = pixels[pos : pos + p_size]
if src_pixel[3] > 0 and src_pixel[3] < 255:
# pixels[pos : pos + p_size] = array("B", [255, 0, 255, 255])
pixels[pos : pos + p_size] = alpha_blend(src_pixel, bg_color, src_pixel[3])
rgn[0:width, 0:height] = pixels.tostring()
# once finished manipulating pixels
layer.flush()
# layer.merge_shadow(True)
layer.update(0, 0, width, height)
def process_layer(image, layer):
pdb.gimp_image_set_active_layer(image, layer)
drawable = pdb.gimp_image_active_drawable(image)
layer_name = pdb.gimp_item_get_name(drawable)
if layer_name == "background":
return
pdb.gimp_selection_none(image)
pdb.gimp_context_set_sample_merged(FALSE)
pdb.gimp_context_set_antialias(FALSE)
pdb.gimp_context_set_sample_transparent(TRUE)
pdb.gimp_context_set_feather(FALSE)
pdb.gimp_context_set_sample_threshold(0)
pdb.gimp_image_select_contiguous_color(image, 2, drawable, 1, 1)
pdb.gimp_selection_invert(image)
non_empty, x1, y1, x2, y2 = pdb.gimp_selection_bounds(image)
if non_empty:
pdb.gimp_image_select_rectangle(image, 2, x1, y1, x2-x1, y2-y1)
non_empty = pdb.gimp_edit_copy(drawable)
if non_empty:
image4 = pdb.gimp_edit_paste_as_new()
active_layer = pdb.gimp_image_get_active_layer(image4)
process_alpha(active_layer)
pdb.file_png_save2(image4, active_layer, "{0}{1}.png".format(savepath, layer_name), layer_name, TRUE, 9, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE)
pdb.gimp_image_delete(image4)
print >> f, "\t\"{0}\": [ {1:d}, {2:d}, {3:d}, {4:d} ],".format(layer_name, x1, y1, x2, y2)
else:
print("gimp_edit_copy = empty ({0})".format(layer_name))
else:
print("gimp_selection_bounds = empty ({0})".format(layer_name))
image = gimp.image_list()[0]
# print image.layers
for layer in image.layers:
process_layer(image, layer)
print >> f, "};"
f.close()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment