A downloadable tool for Windows and Linux
Bitmapflow is a tool to help you generate inbetweens for animated sprites. In other words, it makes your animations smoother. It uses optical flow to try to guess how the pixels move between frames, and blends them accordingly. The results are far from perfect, and probably require some editing by hand afterwards, but sometimes it can produce decent results.
It supports loading and saving animated gifs, spritesheets and individual frames.
You can download it at the bottom of the page. On Windows, you'll need to install the Visual Studio Redistributable first (unless you already have Visual Studio 2015 or newer installed). On Linux, you'll need to install OpenCV 4.2, see the download page for more details. Other than that, it should work out of the box.
A short summary:
- Drag and drop your image into the program. It can be an animated gif, a spritesheet, or individual frames. If you don't have any sprites laying around you can find some in the
examplesfolder in this repository.
- Tweak the parameters.
- Open the File menu to export the results as an animated gif, a spritesheet, or individual frames.
If you use big sprites with lots of frames, you may need to wait a while after tweaking the parameters for the processing to complete, since calculating optical flow can be quite CPU intensive.
A short explanation of the parameters follows.
- Inbetweens: this decides how many inbetweens to generate. For example, if your input animation has 12 frames, and you generate 2 inbetweens, your output animation now has 36 frames. The more inbetweens you have, the smoother your animation gets.
- Loop seamlessly: if enabled, the animation will loop seamlessly. Disable this for one-shot animations, like explosions.
- Motion multiplier: if this value isn't 1x, it will exaggerate the motion if it's >1x, or diminish it if it's <1x. E.g. If you put it at 2x, the motion will go twice as fast; if it's 0.5x, the motion will be cut in half.
- FPS: on the bottom right of the screen, you can change the speed of the input animation, in frames per second (FPS). The output animation will have a higher FPS, depending on the amount of inbetweens. E.g. If your input animation runs at 10 FPS, generating 1 inbetween means your output animation now runs at 20 FPS. Note that this parameter has no effect on the inbetween generation process, it's only used for displaying your sprite. (it does, however, affect the animation speed of exported gifs)
- Flow algorithm: You can decide which optical flow algorithm to use. The default is SimpleFlow, which works well in most cases. If it doesn't work for you, you can switch to DenseRLOF, which works better for some sprites. Both algorithms have different unique parameters to tweak, see below. Note that DenseRLOF seems a little unstable, it occasionally crashes for no reason (I'm using an external library, so I don't have any control over this).
I could explain all the advanced parameters in detail, but since they describe internal optical flow algorithm parameters, they require some background knowledge about the algorithm before they start to make sense. You can check the official documentation for SimpleFlow or the official documentation for DenseRLOF for more details.
You'll need to experiment a lot to find parameters that work well, although the default parameters seem to work decently for a lot of sprites. See my video tutorial on the subject.
The algorithm works best for sprites that only have movement in the two-dimensional plane. That means, things only move horizontally, vertically, or diagonally, not towards or away from the viewer.
Additionally, the algorithm assumes the brightness of pixels doesn't change between frames. That means, things like explosions, particle effects and blinking lights won't work that well, because they generally start bright and become dimmer over time.
Finally, if you feed pixel art into the program, make sure the pixel art isn't upscaled. It should be at its original resolution.
Compiling from source
If you want to dig through the source code and compile Bitmapflow yourself, you can find the source code here.
On Windows, the program crashes after the splash screen, or I get an error about vcruntime140.dll not being found. What to do?
- Install the Visual Studio Redistributable.
On Windows when exporting I get an error similar to "Failed to save spritesheet as [directory and name]; Access is denied (os error 5)."
- Disable your virus scanner and try again. If you don't have a virus scanner enabled, you may not have permission to export into your selected folder (e.g. the Program Files folder may require admin privileges), so try exporting to your own users folder instead.
I get some weird OpenCV error about sizes or something after loading my sprite?
- Try reducing the "layers" parameter in the Advanced parameters section, or click the big Reset button at the bottom of the sidebar. If that doesn't work, your sprite may be too small. Try using a bigger sprite. Also try using SimpleFlow instead of DenseRLOF, it's more versatile and breaks less often.
- DenseRLOF crashes when you use small sprites.
Feel free to use the program for non-commercial and commercial purposes.
The source code is licensed under MIT. The example sprites used in the promotional material (also available in the
examples folder on Github) are licensed as follows:
- CC-BY-3.0 License, created by Luis Zuno (ansimuz):
- CC-BY-AS 3.0 License, created by Balmer and Stephen Challener:
Click download now to get access to the following files:
Log in with itch.io to leave a comment.
Really awesome program! There are some big problems with being able to actually export PNG spritesheets, though:
- the "loop" frames on exported sprite sheets are placed at the very beginning. This offsets the other frames such that the animation no longer actually starts on its intended frame 0. This requires burdensome hand-editing to fix.
- it doesn't remember the last selected frames per row. I would suggest making it auto-calculate frames per row that gets it at close as possible to a square with height and width that are each a power of 2 (thus making the resulting spritesheet more performant for use in games).
- Most importantly, it just doesn't actually work on my computer--like, at all. It throws the error "Failed to save spritesheet as [directory and name]; Access is denied (os error 5)." The program throws this error regardless of which directory I select for it to export to. Even just exporting directly to C: is too much, apparently. The executable itself has Read and Write permissions, so I'm not sure what's going on here. (I am running Windows 10 Home build 19041.867.)
About 1 and 2: I'll look into it.
About 3: have you tried:
- Disabling your virus scanner? (if you have one)
- Exporting to your own Users folder, e.g. C:/Users/[your name here]/? (to avoid permission issues)
- Does loading sprites work as expected? E.g. do loading gifs/spritesheets/individual frames all work correctly?
- Checking the log file? (in the folder where you stored Bitmapflow should be a log file called "bitmapflow.log", can you post its content here?)
Thanks for the response--setting an exception in Avast fixed issue #3! :D
While I'm here, I have a few more bits of feedback for you that will dramatically improve peoples' workflow using this program:
- in the load spritesheet window, the program should auto-calculate the likely frame width by dividing spritesheet width by frames per row. Making the user calculate this and fill in this field in by hand every time seems like an unnecessary inconvenience. (This won't work with packed spritesheets, of course, but a developer would probably want to process their animations before packing anyway.)
- in the load spritesheet window, the program would benefit from a Total rows field below Frames per row. This would allow the program to auto-calculate the likely frame height by dividing spritesheet height by the total number of rows, thereby saving the user the annoyance of checking the spritesheet height and dividing by hand.
- spritesheets oftentimes contain more than one animation on them. Since the algorithm is only meant to blend between frames of a single animation, this means a given spritesheet may to be loaded multiple times; and because the program doesn't remember the values last input when loading a spritesheet, the user has to input them by hand over and over. To fix this, the program should probably just remember the values last used when loading a spritesheet.
- when loading a spritesheet, the program should probably remember the filename of the loaded spritesheet and--when going to Export spritesheet--fill that same filename in by default rather than making the user type it (or a variant of it) out in full every time.
- the increase/decrease arrow buttons to the right of the FPS text field don't respond to clicks.
Thanks for a great program; I look forward to seeing it develop further!
Wow, cool as ice dude, thanks for making life a bit easier. Cheers. Just had to add an exception to Avast to get it to save output.
please please please a linux version OwO
I love this but it won't let me export - I keep getting an OS error 3? "System cannot find the path specified"
Also - is it possible to set a default folder where I could export to? It keeps trying to save to the program files folder - in the Gamesfromscracth video - Mike exports to his desktop?
Try placing the program into another folder (including all other included files), e.g. put it in your Documents folder, then try exporting again. (If you put the program in Program Files you may run into permission issues so don't do that).
The default export folder is the location where you extracted the zip file and ran the program.
Update: turns out this is a bug, you can fix it by ensuring that Bitmapflow and your export folder are on the same drive. (e.g. both paths start with C:/)
I'll publish a fix for this soon.
If I try DenseRLOF on a low resolution Sprite sheet, it will not progress and the complete percentage will stay at zero, and crash the software. I purposely crashed it with task manager open and the memory of the software skyrocketed to 4,000 MB. I had to close it out in task manager before it got too full. SimpleFlow works fine though and the program is crazy useful.
That's a known issue, this is an issue in the library I'm using so I can't do anything about it. Although I guess I could add a minimum sprite resolution...
Looking forward to the Linux version :)
I can't get it to load anything. If I choose spritesheet and select an image, it says the image is "0x0" dimensions and nothing loads. Same with GIF - nothing displays.
I don't get any error messages or anything. Not sure what's wrong.
1. Have you tried loading individual frames too? Does that work?
2. Do you have an antivirus active? If so try disabling it.
I tried loading some images as individual frames, and yes that worked immediately.
But trying to load as "sprite sheet" gives me the sprite sheet import window, but the area where the sprite sheet should be is blank, and the image dimensions listed as "0x0" in the corner.
And similar with loading GIF, except the "before" and "after" windows are just blank.
Seeing as the Individual Frames mode works fine, my guess is that this is some sort of bug.
EDIT: I found out exactly what's causing the problem.
I had a hunch it might have to do with different Drive Letters, and it does. I like to place my portable apps on an external thumb drive located at "Z:\TOOLS\" so this program would be located in "Z:\TOOLS\BitmapFlow\BitmapFlow.exe"
If the program is on the "Z:" drive, it won't load any images from the C:" drive, or any other drive. But if try loading a GIF or Sprite Sheet from the "Z:" drive, it DOES import correctly!
To confirm that it was indeed an issue with the drive letter, I copied over BitmapFlow to the "C:" drive -- to "C:\BitmapFlow\" precisely.
Once it was in the "C:" drive, the exact opposite happened, as I predicted -- only GIFs and spritesheets from the "C:" drive would load, and it would no longer load images from the "Z:" drive.
So there's a bug in your code when reading files where it assumes that the files loaded are on the SAME drive letter as the program itself. So if I have your program located at "Z:\TOOLS\BitmapFlow\BitmapFlow.exe" and try to load a file located at "C:\test\sample.gif" -- my guess is that it tries to load "Z:\test\sample.gif" instead -- which this file path doesn't exist, so it fails to load anything (thus a 0x0 image dimension).
Oddly, this bug doesn't seem to happen when loading as "individual frames". So you may have either used a different code there, or fixed it there and not ported the fix to the other methods.
You should be able to test all of this if you try running the program from a USB drive -- or try loading GIFs from a USB drive that isn't in the same letter as the program.
Thanks for letting me know, I'll look into it.
Update: just tested, can you try using drag and drop instead of loading a file from the file menu? Drag and drop does seem to work for me, but loading from the file menu is indeed broken if the file's on another drive.
This should now be fixed in Bitmapflow v1.0.1.
Don't load the image from a zip file, extract it first
Fantastic now I can make all those rpgmv sprites go from 3 steps to 9 steps.
I waited so long for something like this. All the other auto tween software was either waay too expensive or difficult to use. This kind of software helps people with wrist strain and time restrictions so I needed it, and I do hope it will continue to develop.
I can feel you bud, my carpal tunnel has gotten so bad, I always end up procrastinating
When I save the animation, it shows this error: "Failed to save spritesheet (os error 5)".
Does it work when you save an animated gif? And what about individual frames?
No, it does not work at all neither for animated gifs nor for individual frames. I can't save anything.
That's strange... Are you running out of disk space, perhaps? Or are you on a computer with restricted privileges? (e.g. a school computer?)
I had the same problem, had to add an exception for the bitmapflow folder in Avast Antivirus program. Cheers for the hint.
Tested it on a 3 frame sprite and...
This is ABSOLUTELY insane!
Thank you so much for making and sharing this.