Ripped using NinjaRipper2 on BlueStacks; textures are loaded as required during gameplay, so I still had to play the game! Fast Food Rampage and Heart Attack both have the same data structure, with "assets/spritesheets" containing the PNGS... but they're missing their IDAT, IEND, and other important internal headers! No tool would want anything to do with them; PNG File Chunk Inspector would identitfy the problem and provide dimensions for each file, but not fix it. https://www.nayuki.io/page/png-file-chunk-inspector Thanks to MrGravey, RaccoonSam and Ange Albertini for looking into the files, to no avail. It seems the insides of the PNGs might be compressed via an unusual method, certainly not the 'deflate' protocol typically used by PNGs. The game uses a lot of LUA scripts that are also unreadable in hex tools, possibly encrypted the same way. I had hoped "Scenes/SpriteLoading.lua.jet" might offer some clues, but it's clear if compression is the issue, then that's what needs tackled first. https://discord.com/channels/93774835750014976/1371848861143928904 Anyway! Each spritesheet has a corresponding "TXT.JET" file with coords for each frame -- X, Y, width, height the last 4 values are for padding the canvas for the sake of animation -- left, top, right, bottom Run a Python script to read from the appropriate TXT and PNG to extract them and away you go (no padding) import os from PIL import Image # Define input and output paths input_image_path = "ffr_spritesheet_enemies.png" # Update this to the correct path txt_file_path = "ffr_spritesheet_enemies.txt" # Update this to the correct path output_dir = "cropped_images" # Ensure the output directory exists os.makedirs(output_dir, exist_ok=True) # Open the main image image = Image.open(input_image_path) # Read the coordinates from the TXT file with open(txt_file_path, "r") as file: for line in file: # Split each line by commas parts = line.strip().split(",") # Extract values filename = parts[0] x, y, width, height = map(int, parts[1:5]) # Crop the image cropped_image = image.crop((x, y, x + width, y + height)) # Save the cropped image output_path = os.path.join(output_dir, filename) cropped_image.save(output_path) print(f"Saved: {output_path}") print("Cropping complete!") (padding) import os from PIL import Image, ImageOps # Define input and output paths input_image_path = "large_image.png" # Update this to the correct path txt_file_path = "coordinates.txt" # Update this to the correct path output_dir = "cropped_images" # Ensure the output directory exists os.makedirs(output_dir, exist_ok=True) # Open the main image image = Image.open(input_image_path).convert("RGBA") # Ensure it has an alpha channel # Read the coordinates from the TXT file with open(txt_file_path, "r") as file: for line in file: # Split each line by commas parts = line.strip().split(",") # Extract values filename = parts[0] x, y, width, height = map(int, parts[1:5]) pad_left, pad_top, pad_right, pad_bottom = map(int, parts[5:9]) # Extract padding values # Crop the image cropped_image = image.crop((x, y, x + width, y + height)) # Create a transparent background transparent_bg = Image.new("RGBA", (width + pad_left + pad_right, height + pad_top + pad_bottom), (0, 0, 0, 0)) # Paste the cropped image onto the transparent background transparent_bg.paste(cropped_image, (pad_left, pad_top), cropped_image) # Save the image as PNG to preserve transparency output_path = os.path.join(output_dir, filename) transparent_bg.save(output_path, "PNG") print(f"Saved: {output_path}") print("Cropping and padding complete!")