Using Sprite Sheets in Pygame

When nosotros congenital Alien Invasion, nosotros only needed two images: one for the send, and i for the conflicting. In some games, however, you'll demand lots of different images.

Game developers realized a long time ago that loading many images from dissever files causes a game to run really slowly, so people came up with the idea of sprite sheets. A sprite sail is a single file that contains many smaller images, all on a apparently or transparent background. To use a sprite sail, y'all load the sprite canvas as a unmarried large image, and so you load the individual images from the sprite sheet prototype. This turns out to be much more efficient than loading a agglomeration of separate image files.

For this example we'll expect at how you can load a full set of chess pieces from one sprite canvass. To build a chess game, you lot need 12 pieces: a black and white rex, queen, rook, bishop, knight, and pawn. Instead of loading 12 separate images, we'll load one image that contains an icon for each of these pieces. Nosotros'll then create 12 split objects representing each of these pieces. What you learn in this guide will be useful whatever time you desire to load a number of icons from a single epitome file.

  • A Unproblematic Sprite Sheet
  • Starting a Chess Game
  • Modeling a Chess Piece
  • Modeling a Chess Set
    • The ChessSet class
    • Loading the first piece
    • Loading all the pieces
      • The load_grid_images() method
      • Using load_grid_images()
      • Setting values for name and color
      • Seeing all the pieces
    • Making mistakes
  • Loading Your Own Images
  • Final Words
    • Groups vs Lists
    • Sprite sheets with non-uniform grids
    • Determining margin and padding sizes

A Simple Sprite Sheet

Here's the sprite canvass we'll work with:

I downloaded this epitome from Public Domain Prune Art, and converted it to a .bmp file. You tin right click and relieve the image file from this page, or you can notice information technology in the beyond_pcc folder when you download the resources for the book.

Starting a Chess Game

We're non going to make a chess game in this tutorial, but nosotros'll prepare up this project so yous could go along to expand on it and outset edifice a game if you want to. And so let'due south starting time with a simple Pygame file, just like we did for Alien Invasion. Make a folder chosen chess_game, and salvage this file as chess_game.py:

                          """Chess game, for learning to grab images from a sprite sheet."""              import              sys              import              pygame              from              settings              import              Settings              class              ChessGame              :              """Overall grade to manage game assets and behavior."""              def              __init__              (              self              ):              """Initialize the game, and create resources."""              pygame              .              init              ()              self              .              settings              =              Settings              ()              self              .              screen              =              pygame              .              display              .              set_mode              (              (              cocky              .              settings              .              screen_width              ,              cocky              .              settings              .              screen_height              ))              pygame              .              brandish              .              set_caption              (              "Chess"              )              def              run_game              (              cocky              ):              """Start the primary loop for the game."""              while              Truthful              :              cocky              .              _check_events              ()              self              .              _update_screen              ()              def              _check_events              (              self              ):              for              event              in              pygame              .              effect              .              get              ():              if              event              .              type              ==              pygame              .              QUIT              :              sys              .              go out              ()              elif              event              .              type              ==              pygame              .              KEYDOWN              :              if              event              .              primal              ==              pygame              .              K_q              :              sys              .              exit              ()              def              _update_screen              (              cocky              ):              self              .              screen              .              make full              (              self              .              settings              .              bg_color              )              pygame              .              display              .              flip              ()              if              __name__              ==              '__main__'              :              chess_game              =              ChessGame              ()              chess_game              .              run_game              ()                      

And here'due south settings.py:

                          class              Settings              :              def              __init__              (              self              ):              self              .              screen_width              ,              cocky              .              screen_height              =              1200              ,              800              self              .              bg_color              =              (              225              ,              225              ,              225              )                      

This gives us an empty game window, and nosotros tin press 'q' to quit the game at any fourth dimension. I similar to have this choice because sometimes I run games in fullscreen mode, and you tin can't click the shut button in fullscreen manner.

You'll also need to create an images binder, and relieve the sprite sheet every bit chess_pieces.bmp in this folder.

Modeling a Chess Piece

A chess set is made up of a number of pieces. Let'southward think about the pieces get-go. Each piece needs a name and a colour, and an image. We need to be able to depict each piece to the screen. In a fully implemented game we might add attributes such every bit starting_position, current_position, captured, and others.

We'll brand a file called chess_set.py, which will contain a class for representing pieces and a grade for representing the prepare every bit a whole. Here's the first of that file, with the Slice grade defined:

                          """Module to correspond a chess set, and individual pieces."""              class              Piece              :              """Represents a chess slice."""              def              __init__              (              cocky              ,              chess_game              ):              """Initialize attributes to correspond a ches piece."""              self              .              paradigm              =              None              self              .              proper name              =              ''              self              .              color              =              ''              cocky              .              screen              =              chess_game              .              screen              # Outset each slice off at the pinnacle left corner.                            cocky              .              x              ,              cocky              .              y              =              0.0              ,              0.0              def              blitme              (              cocky              ):              """Depict the slice at its current location."""              self              .              rect              =              self              .              image              .              get_rect              ()              cocky              .              rect              .              topleft              =              self              .              ten              ,              self              .              y              cocky              .              screen              .              blit              (              self              .              image              ,              self              .              rect              )                      

The Piece class allows us to assign each piece an epitome, a name, and a color. Each piece will start off at the top left corner, only we tin move information technology wherever it needs to go. The only argument needed to create a slice initially is a reference to the overall game object. When we're set up to draw a slice to the screen, we can do then by calling blitme().

Modeling a Chess Set

Now we tin first to model the set as a whole. The fix will handle the task of creating all the pieces. In a fuller implementation, it might as well rails attributes such as the overall strength of the player'due south remaining pieces, which can be useful in developing playing strategies.

The ChessSet class

Here'due south the offset of the ChessSet class. To begin with, we want an __init__() method that accepts the overall game object, and we desire to call a helper method that builds the pieces that make up the gear up. Add this code to chess_set.py:

                          """Module to represent a chess set, and individual pieces."""              class              ChessSet              :              """Represents a set of chess pieces.     Each piece is an object of the Piece form.     """              def              __init__              (              self              ,              chess_game              ):              """Initialize attributes to represent the overall set up of pieces."""              self              .              chess_game              =              chess_game              cocky              .              pieces              =              []              self              .              _load_pieces              ()              def              _load_pieces              (              self              ):              """Builds the overall set:         - Loads images from the sprite sail.         - Creates a Piece object, and sets appropriate attributes           for that piece.         - Adds each piece to the group self.pieces.         """              pass              class              Piece              :              --              snip              --                      

We have an __init__() method which accepts a reference to the overall game object, and we have an attribute for storing the pieces in the set. We as well phone call_load_pieces(), which is a stub for at present.

Loading the start slice

When loading images from a sprite sail, it'southward helpful to start with a library if possible. If yous search something like "pygame sprite canvas", one of the top results is from the Pygame wiki. Here's a cleaned-up version of the lawmaking featured in that location:

                          # This grade handles sprite sheets # This was taken from www.scriptefun.com/transcript-2-using # sprite-sheets-and-drawing-the-groundwork # I've added some code to fail if the file wasn't plant.. # Note: When calling images_at the rect is the format: # (x, y, ten + offset, y + offset)                            # Boosted notes # - Further adaptations from https://world wide web.pygame.org/wiki/Spritesheet # - Cleaned up overall formatting. # - Updated from Python ii -> Python 3.                            import              pygame              class              SpriteSheet              :              def              __init__              (              self              ,              filename              ):              """Load the sheet."""              try              :              cocky              .              sheet              =              pygame              .              image              .              load              (              filename              ).              convert              ()              except              pygame              .              error              equally              e              :              print              (              f              "Unable to load spritesheet image:                            {              filename              }              "              )              raise              SystemExit              (              e              )              def              image_at              (              self              ,              rectangle              ,              colorkey              =              None              ):              """Load a specific epitome from a specific rectangle."""              # Loads image from x, y, ten+beginning, y+start.                            rect              =              pygame              .              Rect              (              rectangle              )              image              =              pygame              .              Surface              (              rect              .              size              ).              convert              ()              prototype              .              blit              (              self              .              sail              ,              (              0              ,              0              ),              rect              )              if              colorkey              is              not              None              :              if              colorkey              is              -              one              :              colorkey              =              image              .              get_at              ((              0              ,              0              ))              image              .              set_colorkey              (              colorkey              ,              pygame              .              RLEACCEL              )              return              image              def              images_at              (              cocky              ,              rects              ,              colorkey              =              None              ):              """Load a whole bunch of images and render them as a list."""              return              [              self              .              image_at              (              rect              ,              colorkey              )              for              rect              in              rects              ]              def              load_strip              (              self              ,              rect              ,              image_count              ,              colorkey              =              None              ):              """Load a whole strip of images, and return them as a list."""              tups              =              [(              rect              [              0              ]              +              rect              [              2              ]              *              x              ,              rect              [              1              ],              rect              [              two              ],              rect              [              three              ])              for              x              in              range              (              image_count              )]              render              self              .              images_at              (              tups              ,              colorkey              )                      

Re-create what you lot run across hither and save information technology as spritesheet.py, in the same folder where you saved chess_game.py.

This file contains a class called SpriteSheet that can help usa work with sprite sheets. The method we're most interested in is image_at(). To utilise this, nosotros'll brand an object from the SpriteSheet form, passing it the location of our sprite sheet file. We'll figure out which rectangular portion of the sprite sheet we want to load - the coordinates of its top left corner, and the width and tiptop of the region we want to load. We'll telephone call image_at() with these 4 values.

If y'all look at the file chess_pieces.bmp, you can see that the left border of the black male monarch is nigh 68 pixels from the edge of the image, and the pinnacle of the male monarch is about seventy pixels from the top edge of the image. These will be the first two values we pass to image_at(). The king is nigh 85 pixels broad by 85 pixels tall.

Here's what we'll exercise:

  • Import the SpriteSheet form.
  • Create a SpriteSheet object.
  • Pull the image associated with the rectangle (68, seventy, 85, 85).
  • Create an object from the Piece class.
  • Assign this object the name 'king', the colour 'blackness', and the image we only pulled.
  • Add this object to the list pieces.

We'll do all of this in chess_set.py, in the _load_pieces() method:

                          """Module to represent a chess set, and individual pieces."""              from              spritesheet              import              SpriteSheet              form              ChessSet              :              --              snip              --              def              _load_pieces              (              self              ):              """Builds the overall set:         - Loads images from the sprite sheet.         - Creates a Piece object, and sets appropriate attributes           for that piece.         - Adds each slice to the list self.pieces.         """              filename              =              'images/chess_pieces.bmp'              piece_ss              =              SpriteSheet              (              filename              )              # Create a black king.                            b_king_rect              =              (              68              ,              70              ,              85              ,              85              )              b_king_image              =              piece_ss              .              image_at              (              b_king_rect              )              b_king              =              Piece              (              self              .              chess_game              )              b_king              .              image              =              b_king_image              b_king              .              proper name              =              'king'              b_king              .              color              =              'black'              cocky              .              pieces              .              append              (              b_king              )              class              Piece              :              --              snip              --                      

At that place are many ways nosotros could take washed this. You lot can create the piece first, and and then load the image, or you can load the image and assign it to the slice in one line. I'm doing information technology the mode y'all run into here because in a lilliputian scrap I'k going to show you how to load all the images at in one case, and and so write a loop that creates the pieces all at one time besides.

To see the slice that we grabbed, let's modify the _update_screen() method in chess_game.py:

                          """Chess game, for learning to take hold of images from a sprite sheet."""              import              sys              import              pygame              from              settings              import              Settings              from              chess_set              import              ChessSet              class              ChessGame              :              """Overall class to manage game avails and beliefs."""              def              __init__              (              cocky              ):              """Initialize the game, and create resources."""              pygame              .              init              ()              cocky              .              settings              =              Settings              ()              self              .              screen              =              pygame              .              display              .              set_mode              (              (              self              .              settings              .              screen_width              ,              self              .              settings              .              screen_height              ))              pygame              .              display              .              set_caption              (              "Chess"              )              cocky              .              chess_set              =              ChessSet              (              self              )              def              run_game              (              self              ):              """Start the chief loop for the game."""              while              True              :              self              .              _check_events              ()              self              .              _update_screen              ()              def              _check_events              (              self              ):              for              upshot              in              pygame              .              event              .              get              ():              if              consequence              .              blazon              ==              pygame              .              QUIT              :              sys              .              go out              ()              elif              event              .              type              ==              pygame              .              KEYDOWN              :              if              event              .              key              ==              pygame              .              K_q              :              sys              .              exit              ()              def              _update_screen              (              cocky              ):              cocky              .              screen              .              fill              (              self              .              settings              .              bg_color              )              # Draw the black male monarch in its current position.                            self              .              chess_set              .              pieces              [              0              ].              blitme              ()              pygame              .              display              .              flip              ()              if              __name__              ==              '__main__'              :              chess_game              =              ChessGame              ()              chess_game              .              run_game              ()                      

We first import ChessSet. Then in __init__() we make an attribute called chess_set, which is an object of the ChessSet class. This object needs a reference to the overall game object, which in this file is represented by self. In _update_screen(), we call blitme() on the first (and but) slice in the fix.

The output shows the black king in the upper left corner of the game window:

Nosotros've pretty much got the image we want. We might want to go back and refine the rectangle we used for pulling this image, to even out the amount of background on each of the margins.

Don't be surprised if you lot run into a much dissimilar expanse of the sprite sheet than you were expecting when you run your own lawmaking. It can take a bit of exercise to understand how to choose the right rectangle coordinates, and even with practice information technology's piece of cake to brand a error that grabs the wrong role of the sprite sheet. If you run into a blackness rectangle, it's possible you lot asked for a portion of the sprite sheet that doesn't exist.

Loading all the pieces

As mentioned earlier, it'south possible to load all of the images nosotros demand from the spritesheet at once, and then assign each one to the appropriate piece. This tin be much easier than figuring out the coordinates by hand for each private piece, especially if y'all're working with multiple sprite sheets.

Consider the original sprite sail again, this time with a couple aspects of the sheet highlighted:

The dark blue rectangle shows the space to the left of the first column, which we can call a margin. The light blueish region shows the horizontal infinite between columns, which we tin telephone call padding. The dark greenish bar shows the margin above the first row, and the light green bar shows the vertical padding between each row.

These spacings let united states of america to piece of work out a design for where each epitome should be grabbed. For example the left position of the black king is equal to the width of the horizontal margin. The left position of the black queen is equal to the width of the horizontal margin, plus the width of a piece, plus the width of one strip of padding. For the third icon in the first row, the horizontal position is one margin width, plus two padding widths, plus ii icon widths. The width of an icon should exist the width of the overall image, minus the space taken past the margins and padding, divided past the number of columns.

If you want a challenge, endeavour adding a method chosen load_grid_images() to SpriteSheet. The method should take in the post-obit arguments: num_rows, num_cols, x_margin, x_padding, y_margin, and y_padding. The method should utilize these values to figure out the width and pinnacle of each piece, and call image_at() with the appropriate parameters. You should be able to telephone call load_grid_images() with the advisable values, and the method should return a listing of all sprites in the sprite sheet. If you lot desire to endeavour this, break and effort it at present, because I'yard going to prove that method and and so nosotros'll use it to load the rest of the pieces.

The load_grid_images() method

Here's the load_grid_images() method, which we can add together on to the finish of SpriteSheet:

                          --              snip              --              class              SpriteSheet              :              def              __init__              (              self              ,              filename              ):              --              snip              --              def              image_at              (              self              ,              rectangle              ,              colorkey              =              None              ):              --              snip              --              def              images_at              (              self              ,              rects              ,              colorkey              =              None              ):              --              snip              --              def              load_strip              (              cocky              ,              rect              ,              image_count              ,              colorkey              =              None              ):              --              snip              --              def              load_grid_images              (              self              ,              num_rows              ,              num_cols              ,              x_margin              =              0              ,              x_padding              =              0              ,              y_margin              =              0              ,              y_padding              =              0              ):              """Load a grid of images.         x_margin is space between top of sail and top of starting time row.         x_padding is space between rows.         Assumes symmetrical padding on left and correct.         Same reasoning for y.         Calls self.images_at() to become list of images.         """              sheet_rect              =              cocky              .              sheet              .              get_rect              ()              sheet_width              ,              sheet_height              =              sheet_rect              .              size              # To calculate the size of each sprite, subtract the two margins,                            #   and the padding betwixt each row, then divide by num_cols.                            # Aforementioned reasoning for y.                            x_sprite_size              =              (              sheet_width              -              2              *              x_margin              -              (              num_cols              -              ane              )              *              x_padding              )              /              num_cols              y_sprite_size              =              (              sheet_height              -              ii              *              y_margin              -              (              num_rows              -              ane              )              *              y_padding              )              /              num_rows              sprite_rects              =              []              for              row_num              in              range              (              num_rows              ):              for              col_num              in              range              (              num_cols              ):              # Position of sprite rect is margin + one sprite size                            #   and one padding size for each row. Same for y.                            x              =              x_margin              +              col_num              *              (              x_sprite_size              +              x_padding              )              y              =              y_margin              +              row_num              *              (              y_sprite_size              +              y_padding              )              sprite_rect              =              (              x              ,              y              ,              x_sprite_size              ,              y_sprite_size              )              sprite_rects              .              append              (              sprite_rect              )              grid_images              =              cocky              .              images_at              (              sprite_rects              )              print              (              f              "Loaded                            {              len              (              grid_images              )              }                              grid images."              )              render              grid_images                      

This might await like a long method, but it'southward just near 15 lines of code. Existent-world functions and classes can include more than comments than yous typically see in books. It's besides a niggling longer than it needs to exist, for clarity in a tutorial. For example if yous didn't need to run across how many images were loaded, you could collapse the last three lines into i line:

                          return              self              .              images_at              (              sprite_rects              )                      

Using load_grid_images()

We'll showtime use this method to load all the images, and run across if information technology'south grabbing all the correct portions of the sprite sheet. We'll do this in _load_pieces(), in ChessSet:

                          def              _load_pieces              (              cocky              ):              """Builds the overall set:         - Loads images from the sprite sheet.         - Creates a Piece object, and sets appropriate attributes           for that piece.         - Adds each slice to the list self.pieces.         """              filename              =              'images/chess_pieces.bmp'              piece_ss              =              SpriteSheet              (              filename              )              # Load all piece images.                            piece_images              =              piece_ss              .              load_grid_images              (              2              ,              six              ,              x_margin              =              64              ,              x_padding              =              72              ,              y_margin              =              68              ,              y_padding              =              48              )              # Create a new Slice object for every image.                            for              image              in              piece_images              :              piece              =              Piece              (              self              .              chess_game              )              piece              .              image              =              image              self              .              pieces              .              append              (              piece              )                      

We utilize load_grid_images() to load ii rows with 6 columns each, and specify appropriate margin and padding amounts. We and then create one Slice object for every image that was loaded; we'll take care of setting the proper noun and color values in a moment.

When nosotros run chess_game.py again, we should run into the black king in the upper left corner, since it was the first slice loaded. This works; the game window looks but like information technology did when nosotros loaded a single image, with a slightly dissimilar cropping region.

Setting values for proper name and color

In that location's a pattern in the sprite sheet, which we tin use to efficiently set the name and color values for each piece. We'll create a list of colors, and a list of piece names. Then we'll set upwardly nested loops that cycle through the pieces in the same order that load_grid_images() works, ane row at a time.

Here'south the consummate _load_pieces():

                          def              _load_pieces              (              self              ):              """Builds the overall set:         - Loads images from the sprite sheet.         - Creates a Piece object, and sets appropriate attributes           for that piece.         - Adds each slice to the listing self.pieces.         """              filename              =              'images/chess_pieces.bmp'              piece_ss              =              SpriteSheet              (              filename              )              # Load all piece images.                            piece_images              =              piece_ss              .              load_grid_images              (              2              ,              half dozen              ,              x_margin              =              64              ,              x_padding              =              72              ,              y_margin              =              68              ,              y_padding              =              48              )              # Create a Slice for each image.                            colors              =              [              'black'              ,              'white'              ]              names              =              [              'rex'              ,              'queen'              ,              'rook'              ,              'bishop'              ,              'knight'              ,              'pawn'              ]              piece_num              =              0              for              color              in              colors              :              for              proper name              in              names              :              piece              =              Slice              (              self              .              chess_game              )              piece              .              proper name              =              proper noun              piece              .              color              =              color              piece              .              image              =              piece_images              [              piece_num              ]              cocky              .              pieces              .              suspend              (              slice              )              piece_num              +=              1                      

We load all the piece images, just every bit we did before. And so we set a counter, piece_num, to continue rails of how many pieces nosotros've made. This will serve as an alphabetize to the image we want from the list piece_images. We loop through the colors, and and so through the names. This will event in processing each of the black pieces, then each of the white pieces. For each piece, we set the appropriate values, add it to the list self.pieces, and increment the value of piece_num.

When we run chess_game.py over again, we should still see the black king because it'south always the first slice in the list.

Seeing all the pieces

Now let's bank check that all of the pieces were pulled correctly. Nosotros can do this in _update_screen(), in chess_game.py:

                          def              _update_screen              (              cocky              ):              self              .              screen              .              make full              (              self              .              settings              .              bg_color              )              # Depict a row of blackness pieces.                            for              index              ,              piece              in              enumerate              (              self              .              chess_set              .              pieces              [:              half-dozen              ]):              piece              .              x              =              alphabetize              *              100              piece              .              blitme              ()              # Depict a row of white pieces.                            for              index              ,              slice              in              enumerate              (              self              .              chess_set              .              pieces              [              6              :]):              slice              .              10              =              alphabetize              *              100              piece              .              y              =              100              piece              .              blitme              ()              pygame              .              brandish              .              flip              ()                      

Nosotros loop through the start half-dozen pieces. For each piece, we set the ten value 100 higher than the piece before it. If you haven't seen the enumerate() function yet, information technology'south mentioned on page 335 in the book. The enumerate() office returns the index and the value of each item equally yous loop through a list. We do the aforementioned for the white pieces, except nosotros set up the y value to 100 and then they announced equally a 2nd row.

Here we can run across that all of the pieces were grabbed appropriately:

Making mistakes

When you're reading a tutorial like this, information technology'due south easy to think that everything is supposed to work out perfectly the get-go time you write your code. That'southward not at all the case! I made a number of mistakes in the process of working out load_grid_images(), and more mistakes when using information technology to grab the images for each piece. For case when I beginning chosen load_grid_images(), I mixed up the values for the number of rows and columns. When I ran chess_game.py, I saw a blank game window. I had no idea why the images weren't being grabbed. I concluded upwardly looking at the value of sprite_rect in load_grid_images(), and saw that the width of the paradigm being grabbed was negative. That led me back to looking at the values I was passing to load_grid_images(), and I spotted the mixup. But it took a while, and it was non at all obvious what was going on at first.

If I were going to use this module to create a lot of games using sprite sheets, or if I was maintaining this for a widely-distributed bundle, I'd probably add some error-checking code to make sure all of the sizes in load_grid_images() come out positive. But I'm trying to keep things simple for now, so I'chiliad not calculation that caste of error-checking at this point.

If you see mistakes in the game you're working on, or any project y'all notice yourself involved in, please know that anybody makes mistakes almost every unmarried day. Y'all are not lone. :)

Loading Your Own Images

Some people like to identify files like spritesheet.py in a directory chosen utils within their main projection folder, and then their import statement looks like this:

                          from              utils.spritesheet              import              SpriteSheet                      

This makes it clear what code is specific to your game, and what code is a utility module that could exist used for any game. If you're making a lot of games, y'all can place the utils directory in a location that'due south accessible to all your games, so you don't have a bunch of copies of the same utility module all over your system.

You can observe the full spritesheet.py module here. Information technology'southward as well in the beyond_pcc folder in the zip file of online resources for the volume. If you don't meet that folder, you might need to download a newer copy of the online resource, as I've just recently added this section.

Terminal Words

Groups vs Lists

The betoken of this guide was to show how you tin load images from a sprite sheet when using Pygame. There's a lot that we might do differently if nosotros were focused on edifice a fully-functioning chess game. For case, should nosotros store the pieces in a list like nosotros did, or should they exist placed into a Pygame Grouping? I used a list here considering a list is ordered, and I wanted the order of cocky.pieces to match the order we see in the sprite sheet. A group is not ordered, so it wouldn't necessarily work for this purpose. A group is nifty when you want to repeatedly draw a bunch of elements to the screen, and the gild you're keeping them in doesn't matter.

Sprite sheets with not-compatible grids

Many sprite sheets are prepare in a filigree like we saw with chess_pieces.bmp. For example a deck of cards might have four rows of 13 cards each, and perchance an actress row for a card back and a joker. Still, some sprite sheets have icons of different sizes on them. In that case you might be able to call load_grid_images() for most of the icons, and then call image_at() for some of the oddly-sized icons.

Determining margin and padding sizes

If you're not sure how to decide pixel sizes on a sprite canvass, attempt opening the file in an image previewer or editor. Nearly viewers and editors allow you lot to make selections in a way that shows you the dimensions of the selection in pixels. For case on macOS y'all can open Preview, click Tools > Rectangular Selection, and drag a rectangle effectually the region you want to measure. A small popup will evidence you lot the width and height of the rectangular region you have selected.

If you're completely at a loss, make a guess and see how accurately the first epitome is grabbed. That should allow you to work out the size of the margins, and looking at the second prototype should allow you to work out the padding.