Turning Flipbook Images into data that can go through each image in Flipbook

Hey developers, I’m looking into making a script that can turn an image, into data that can be used in a image label to display each frame of a flipbook image… For example…

This is a Flip book image frame by frame (from roblox):

How can I make something like this:

local Example = {
[1] = "Data to make it show frame one", 
[2] = "Data to make it show frame two", 
--Etc
}

local function ImageIntoFlipbookData(FramesNumber) 
--do something here
    return Example
end

local AllFrames =  ImageIntoFlipbookData("A number here") 

ImageLabel.ChangeSomething = AllFrames[1]

--And that would make it the first frame..

I don’t know how I can do this so some ideas might be helpful… Its important to mention that:

I want this to work for any frame number. So like if the frames (FramesNumber) were 10, a 3x3 grid won’t work, but it will assume the Creator went to the nearest supporting flipbook, (made a 4x4 flipbook in this example), and left the last 6 empty. Make sense? (This system will assume that all frames take up the whole image, unless frames that are empty)

Any help, or point in the right direction is helpful and appreciated!

2 Likes

if it helps, I got something that will get if its a 1x1, 2x2, 3x3 etc. flipbook based on Frame Number (I think). I just don’t know how I can use this information…

local function ImageIntoFlipbookData(FramesNumber) 
    if FramesNumber <= 0 or FramesNumber ~= math.round(FramesNumber) then return end
     local GuessXbyX = 0
     repeat 
       GuessXbyX += 1
     until GuessXbyX *  GuessXbyX >= FramesNumber
end
3 Likes

Still very confused as I don’t know what to do

1 Like

I understand that you want to play a flipbook on an image label, so I’ll write a little tutorial on how to.

  1. Firstly, you will have to bulk import all of your PNG’s into roblox using the asset manager. I found a simple 64 frame flipbook on my PC so i’ll be using that one. Bulk importing 64 images will take a little time (obviously), took around 10 minutes for me (64 frames/pngs)

  2. I will then make a folder called “Frames” in ReplicatedStorage (Or anywhere you want tbh) and place all of the images into the folder. Insert all of the imported decals and name them by number. This is what i have done:

  3. Now we encounter a problem. if you just change the image id of the image label, there will be a little white flicker before the new image loads. using an additional step we create “ghost frames” which are then played by just making the next frame dissappear.

task.wait()

local flipbook_pngs = game.ReplicatedStorage.Frames
local base = script.Parent.Base

function initialize_flipbook()
	
	local frames = Instance.new("Folder")
	frames.Parent = base.Parent
	frames.Name = "ghost_frames"

	for step = 1, #flipbook_pngs:GetChildren(), 1 do
		
		local current_frame : Decal = flipbook_pngs:FindFirstChild(tostring(step))
		local ghost_frame = base:Clone()
		
		ghost_frame.Parent = base.Parent.ghost_frames
		ghost_frame.Image = current_frame.Texture
		ghost_frame.Name = tostring(step)
		
		ghost_frame.Visible = true;
		ghost_frame.ImageTransparency = 1
		ghost_frame.BackgroundTransparency= 1
		
	end
end

function preload_flipbook()
	
	local ghost_frames = script.Parent.ghost_frames

	for step =1, #ghost_frames:GetChildren() do
		
		local current = ghost_frames:FindFirstChild(tostring(step))
		current.ImageTransparency = 0;
		current.BackgroundTransparency = 0
		
		task.wait(1/64)
		
		if step == #ghost_frames:GetChildren() then
			play_flipbook()
		end
	end
end

function play_flipbook()
	
	local ghost_frames = base.Parent.ghost_frames
	
	for _, ghost_frame in ipairs(ghost_frames:GetChildren()) do
		
		ghost_frame.ImageTransparency = 1
		ghost_frame.BackgroundTransparency= 1
		
	end
	
	for step =1, #ghost_frames:GetChildren() do

		local current = ghost_frames:FindFirstChild(tostring(step))
		current.ImageTransparency = 0;
		current.BackgroundTransparency = 0
		
		task.wait(1/32) -- change 64 with the FPS you want

	end
end

initialize_flipbook()

task.delay(3, function()
	print("Playing flipbook")
	preload_flipbook() 
end)

The code can be optimized a loooooottt

ideally, you would do the preloading step in an area not visible to the player and then play it where the player can see it (edit the functions a little). The preloading function is necessary since during my testing without it a white flicker would be prevelant while the flipbook was playing. the code is far from optimal but you can study it and write something of your own :slight_smile:

this is the result i get: (the white frames in the beginning is just the sequence being preloaded).

hope i helped :slight_smile:

Edit: “base”, in the code refers to an image label, sorry didnt put that in earlier :smile:
image

2 Likes

Thanks for your reply, but Thats not what I want. I want to be able to use one image, in other words a flipbook and turn it into each frame, make sense? I only want one image to be turned into how many frames is made in that flipbook.

And mostly I want to do it this way because of roblox moderation. I only need one 8x8 instead of uploading 64 different images.

I actually have my own script for what you were trying to do above :

local function PreloadImages(Folder)
    game:GetService("ContentProvider"):PreloadAsync(Folder:GetChildren()) --Load images before they are used
end

local function PlayAnimation(ChangedImageLabel, Folder, WaitAfterEachFrame)
     local WhereWeAt = 0
    repeat 
        ChangedImageLabel.Image = Folder:FindFirstChild(WhereWeAt).Image --Turn the Image Lable into that image
        task.wait(WaitAfterEachFrame) --Wait a certain amount
    until Folder:FindFirstChild(WhereWeAt + 1) == nil --Ends when we can't find a frame
end

PreloadImages(game.ReplicatedStorage.ImagesFolder.Animations.Explode) --Load the folder images

repeat  --This is only here for an endless animation
   PlayAnimation(Script.Parent, game.ReplicatedStorage.ImagesFolder.Animations.Explode, 0.1)
task.wait(0.5)
until false

You can use imagerectoffset paired with imagerectsize to do this. I’ll try to write up something for you rq.

Edit: Also to clarify you want to make it so that each individual frame can be displayed right?

PS: sup its been a second lol

1 Like

Hello, It has been a bit haha…

An example would be nice on how I could achieve.

Yep. Basically I want a function to return a table with data to make it each one frame…, withg the ,last number being the last frame… Like:

At the moment, I don’t think it is possible to get the number of frames in the image but this should give you a start. It returns data of 2 properties needed to change the positioning of the image to make it display a frame. I believe you can just do like imagelabel.imagerectoffset or something to change it.

local imdims = Vector2.new(750,750)
local flipims = 64

function getims(imdims, flipims)
	local data = {}
	
	local w, h = math.sqrt(flipims), math.sqrt(flipims)
	local imsize = imdims/w -- w and h are going to be the same
	
	for height = 0, h-1 do
		for width = 0, w-1 do
			table.insert(data, {
				["ImageRectSize"] = imsize,
				["ImageRectOffset"] = Vector2.new(width * imsize.X, height * imsize.Y)
			})
		end
	end
	
	return data
end

print(getims(imdims, flipims))

(Also untested code T^T)

Edit: I gtg but if this doesn’t work just tell me what’s wrong.

1 Like

Works great thank you so much! I’ll let you know if any issues happen, but in my tests, it looks great

1 Like

Whoopsie I think I flipped the width and height loops. Put the width in the height loop instead (I’ll edit real quick).

1 Like

An issue I ran into…

Can I get this Number based on the image itself and how many frames exist. Because for example, a 2x2 I was testing with was Vector2.new(1000,1000)… I don’t know what this number is based off of.

It is the image resolution. So if you have a 750 px by 750 px image like the one you first posted, that is what you would put. I’m not sure about how to get the dims of a posted image though… If you have the image downloaded though, you can just check the properties tab in file explorer or finder.

Is there a way I could get this number by roblox scripts? b(I’m assuming not based on what I read but idk) What I’m making is a roblox script that others would use, so it would be nice to be able to get that information via roblox script as I won’t be making all the flipbooks

As far as I know, as of now, it isn’t possible without using external code using https.

1 Like

Apparently, you can scale down asset images using “http://www.roblox.com/Thumbs/Asset.ashx?width=420&height=420&assetId=idhere”. Not sure if it works, you can try to test it.

Reference.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.