Bad Apple! / Compressed video proof of concept

I did a hard work to create an image compression library for arduboy ( Unfortunately only few people knows about it. :pensive:

After cropping the gif to the visible 64x64 pix and using the compressor I had these results:

// File: bad2.gif (207 frames)
// Size: 207x64x64px (105984 bytes)
// Compressed: 13696 bytes
// Ratio: 0.12922706

Sketch uses 22,014 bytes (76%) of program storage space.

Sketch can be generated with one command line.
Please, ask me if you have any issue with the lib. Thanks!


Write and article about it for the Arduboy Magazine. That may get more people interested in using it.


is somewhere a final code for full “bad apple” animation on Arduboy )

Holy necropost batman, an image compression algorithm?

This combined with the FX chip could be quite epic. @Mr.Blinky What do you know? :wink:

1 Like

The demo was a quick and dirty play raw frames from flash. Maybe I should make a real demo with out of it?

You don’t want to know what i know :wink:

1 Like

Yah but compressed video!

I dream of seeing a new hope on arduboy!

It would be cool.

1 Like

this quality is nice but i can’t find the source code with gfx data to play it on arduboy

The code is generated from the java encoder ([]) with the “-gs” option and this animated gif. The code only plays the compressed frames sequentially.



how much it will need space for full video encoded?
i’m not experienced to do things with java so maybe somebody can help to get “ino” or “h” with all the video gfx in uint8_t PROGMEM [].
i would like to try play full video on Arduboy and ESPboy
may be not full on Arduboy (lack of memory problem) but full on ESPboy

Full “Bad apple” 64x64 video works fine on the ESPboy
3.39min, 10fps

“Sketch uses 589072 bytes (56%) of program storage space. Maximum is 1044464 bytes.
Global variables use 42496 bytes (51%) of dynamic memory, leaving 39424 bytes for local variables. Maximum is 81920 bytes.”

we still have free PROGMEM 455392 bytes!
probably it’s possible to rewrite the “ArdBitmap-master” lib to run out of the Aruduboy 64x128 limits and run this video full screen 128x128

1 Like

Great! lib has a limit of 128x64 pix, but you could split 128x128 images and draw 2 compressed pics per frame.

1 Like

Nice! also with those screws I imagine you get custom fingertips :crazy_face:


Oof this nerd-sniped me hard… Here’s my attempt:
ardu_apple.ino.leonardo.hex (76.2 KB)

Entire video at 5 FPS (1080 frames) at 24x20 resolution (up-scaled to 72x60). Binary at 27738 Bytes.

Encoding per frame (avg ~20.5 bytes/frame):

  • Bytes[0-2] – 30 bits where each bit represents a 4x4 block that hasn’t changed since last frame. Two left over bits: one for the color of the first RLE encoded pixel, the other for the RLE direction.
  • Byte[3] – N number of nybbles in RLE in this frame
  • Byte[4-N] – Each nybble represents the length of the current run of color, alternating between black and white.


  • Reduce entropy on each frame by dilating/eroding the image.
  • RLE can be horizontal or vertical, we choose the shorter one of course. The runs simply skip over the blocks that have not changed since last frame.
  • We greedily look at the surrounding frames and pick the one that reduces entropy between frames.
  • Not shown in this build, but we can introduce lossy-ness by treating some blocks that have minimal change since last frame. This produced stray pixel artifacts, but reduces the encoding to ~17.6 bytes/frame if we ignore %100 of 1-pixel changes. The artifacts are barely noticeable at 20%.
  • Also not in this build, but we can ignore some pixels by omitting "1"s in the RLE.


  • I started adding music, but got bored.

Code here: GitHub - justecorruptio/ardu_apple

1 Like

Woof the emulator doesn’t like it one bit haha! That is a lot of content although its tough to see what’s going on cuz of the resolution but if you know the video then you can kinda follow along.

Very impressive, do you know what the duration is of the video?

Can you increase the resolution some? I’ve been looking for a heavy compression for video for some time…

We have the external memory now, so imagine what we could do with 16MB!!

I wonder if it’s at all possible to get starwars episode 4, or really any feature length film onto the arduboy. If there is a sound compression that could go along with it would be pretty incredible!

Either way, nice work!!

That was supposed to be 5 FPS * 1080 frames is about 3 minutes. Though we can change the fps and lossiness, so you can push it farther.

Here’s an example of 36x32 resolution with some lossiness in the form of stray pixels:
ardu_apple.ino.leonardo.hex (66.7 KB)

This is ~40 bytes/frame.

So at 36x32, Episode 4 (125 mins) * 60sec/min * 10 fps * 40 B/f ~= 3MB… which doesn’t sound horrible.

My current encoding can’t represent 64x64 without extending the the bits used to represent the length of a frame (but it’s ~ 100 bytes/frame), so episode 4 would b ~7.5 MB.

I will say that RLE i’m using here is reallllly optimized for silhouettes, and anything else probably won’t do well.

ardu_apple.ino.leonardo.hex (77.5 KB)

Ok, got it to 64x68 resolution. Was able to fit 375 frames with a bit of lossiness.

Also here’s some Star Wars:

ardu_apple.ino.leonardo.hex (74.4 KB)