Advertisement
Guest User

Spritesheet plugin for GIMP. Converts layers (like animated GIFs frames) to a spritesheet

a guest
Feb 25th, 2021
292
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.00 KB | None | 0 0
  1. #!/usr/bin/env python2
  2. # License: Public Domain - https://creativecommons.org/share-your-work/public-domain/cc0/
  3.  
  4. from gimpfu import *
  5. import math
  6.  
  7. def create_spritesheet(image, singleRow, widthCells, heightCells):
  8.  
  9.     # Grab all the layers from the original image, each one of which will become an animation frame
  10.     layers = image.layers
  11.     numLayers = len(layers)
  12.  
  13.     # Work out how many rows and columns we need for each of our layers/animation frames
  14.     if singleRow:
  15.         numRows = 1
  16.         numCols=numLayers
  17.     else:
  18.         if widthCells != 0 or heightCells !=0:
  19.             if widthCells !=0 and heightCells !=0: #fixed
  20.                 numRows=heightCells
  21.                 numCols=widthCells
  22.             else:
  23.                 if widthCells !=0: #width given, calculate height
  24.                     numCols=widthCells
  25.                     numRows=int(math.ceil(numLayers/widthCells))
  26.                 else: #height given, calculate width
  27.                     numRows=heightCells
  28.                     numCols=int(math.ceil(numLayers/heightCells))
  29.         else: #auto
  30.             numRows=int(math.ceil(math.sqrt(numLayers)))
  31.             numCols=numRows
  32.  
  33.     # And then determine the size of our new image based on the number of rows and columns
  34.     newImgWidth = image.width * numCols
  35.     newImgHeight = image.height * numRows
  36.  
  37.     # Create a new image and a single layer that fills the entire canvas
  38.     newImage = gimp.Image(newImgWidth, newImgHeight, RGB)
  39.     newLayer = gimp.Layer(newImage, "Spritesheet", newImgWidth, newImgHeight, RGBA_IMAGE, 100, NORMAL_MODE)
  40.     newImage.add_layer(newLayer, 1)
  41.  
  42.     # Clear any selections on the original image to esure we copy each layer in its entirety
  43.     pdb.gimp_selection_none(image)
  44.  
  45.     # Layers are in the reverse order we want them so start at the end of the list and work backwards
  46.     layerIndex = (numLayers - 1)
  47.  
  48.     # Loop over our spritesheet grid filling each one row at a time
  49.     for y in xrange(0, numRows):
  50.         for x in xrange(0, numCols):
  51.             #Pre-process the layer to make sure we copy over a layer with a size the same as the image
  52.            
  53.             #Get layer's size and offsets to restore after copying its contents over
  54.             lOffX, lOffY=pdb.gimp_drawable_offsets(layers[layerIndex])
  55.             lW=pdb.gimp_drawable_width(layers[layerIndex])
  56.             lH=pdb.gimp_drawable_height(layers[layerIndex])
  57.             #Resize the layer to image size
  58.             pdb.gimp_layer_resize_to_image_size(layers[layerIndex])
  59.             # Copy the layer's contents and paste it into a "floating" layer in the new image
  60.             pdb.gimp_edit_copy(layers[layerIndex])
  61.             floatingLayer = pdb.gimp_edit_paste(newLayer, TRUE)
  62.             #Restore the original layer's size and offsets
  63.             pdb.gimp_layer_resize(layers[layerIndex], lW, lH, -lOffX, -lOffY)
  64.  
  65.  
  66.             # This floating layer will default to the center of the new image so we first shift to the top left
  67.             # corner (0, 0) and and then shift to correct grid position based on current row and column index
  68.             xOffset = (-newImgWidth/2) + (image.width/2) + (x * image.width)
  69.             yOffset = (-newImgHeight/2) + (image.height/2) + (y * image.height)
  70.  
  71.             # GIMP will only copy non-transparent pixels, so if our image contains transparency
  72.             # the new floating layer may be smaller than we want which will cause animation issues.
  73.             # To resolve this we adjust our position by the difference in layer size to ensure everything aligns
  74.             xOffset += (image.width - floatingLayer.width) / 2
  75.             yOffset += (image.height - floatingLayer.height) / 2
  76.  
  77.             # Move the floating layer into the correct position
  78.             pdb.gimp_layer_translate(floatingLayer, xOffset, yOffset)
  79.  
  80.             # Move to the next layer, unless we're all done in which case exit!
  81.             layerIndex = (layerIndex - 1)
  82.             if layerIndex < 0:
  83.                 break;
  84.  
  85.     # Merge the last floating layer into our final 'Spritesheet' layer
  86.     pdb.gimp_image_merge_visible_layers(newImage, 0)
  87.  
  88.     # Create and show a new image window for our spritesheet
  89.     gimp.Display(newImage)
  90.     gimp.displays_flush()
  91.  
  92. # Register the plugin with Gimp so it appears in the filters menu
  93. register(
  94.     "python_fu_create_spritesheet",
  95.     "Creates a spritesheet (in a new image) from the layers of the current image.",
  96.     "Creates a spritesheet (in a new image) from the layers of the current image.",
  97.     "Author: Karn Bianco. Contributors: Eneko Castresana",
  98.     "Author: Karn Bianco. Contributors: Eneko Castresana",
  99.     "2018",
  100.     "Create Spritesheet",
  101.     "*",
  102.     [
  103.         (PF_IMAGE, 'image', 'Input image:', None),
  104.         (PF_BOOL, "singleRow", "Output to a single row?", FALSE),
  105.         (PF_INT, "widthCells", "Width cells (0 for auto)", 0),
  106.         (PF_INT, "heightCells", "Height cells (0 for auto)", 0)
  107.     ],
  108.     [],
  109.     create_spritesheet, menu="<Image>/Filters/Animation/")
  110.  
  111. main()
  112.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement