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):
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!
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
I understand that you want to play a flipbook on an image label, so I’ll write a little tutorial on how to.
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)
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:
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
this is the result i get: (the white frames in the beginning is just the sequence being preloaded).
hope i helped
Edit: “base”, in the code refers to an image label, sorry didnt put that in earlier
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
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.
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