Cleanly modifying animatedgifs to draw each frame?


#1

Hi @Louis
I have a 64x96 display, so I’d like to scroll some 64x64 animated gifs while I’m animating them.
Sadly the library is being too smart and efficient and only redraws the pixels that need to be, making things not work if I change the drawing offset between frames.

From reading the code, it looked like this would work:

int GifDecoder<maxGifWidth, maxGifHeight, lzwMaxBits>::decodeFrame(bool kf) {
    if (kf) {
        keyFrame = true;
        prevDisposalMethod = DISPOSAL_NONE;
        transparentColorIndex = NO_TRANSPARENT_INDEX;
    }

That said, this did not work like I was hoping it would.
Any idea if what I’m trying to do is easily possible, or not so much?


#2

Not sure about your changes. I suggest manually copying/moving the pixels when you change the offset. Use the backbuffer feature, see FastLED_Functions example


#3

I might not understand your question fully, late here. Sorry I’m out of time


#4

(first, yeah, using my new shirt tonight, but it’s really a prototype where not everything works. I already made my peace with animated gifs not working while being scrolled).

Thanks. You did understand my question. You are correct that I can copy the pixels from my buffer to the backbuffer and add an offset then, but that’s more complicated code-wise and gets even worse if I want to do a move in the X axis vs Y axis (scrolling an animated gif that is 48 pixels across in a 64 pixel area).
Right now I simply modified the drawPixel function to offset the drawing, which works great with very little code.

So, back to the issue: I’m not sure how much of the animatedgifs decoding code you wrote, but yeah, it would be a lot easier for me if I can simply tell that code to render the entire frame and do a clear before each frame is rendered.
That’s what I do now, but indeed it doesn’t work well unless I can force each frame to be fully rendered, and right now it only draws the pixels that changed on most gifs as opposed to drawing all the pixels of each frame.


#5

The animated gifs didn’t work so well yet, but I had enough demo code I was able to work with to get some nice shots.
A few details here New SmartMatrix::GFX based shirt


#6

Barely any.

From skimming through the code just now and what I recall of how Animated GIFs work, I don’t think it’s possible for the decoder to redraw an entire frame. This buffer stores pixel data, but it’s stored with an indexed color palette, not RGB, and that palette can change mid-GIF.

uint8_t imageData[maxGifWidth * maxGifHeight];

I’d suggest modifying the drawPixelCallback() function to draw to another rgb24 buffer, and you can then move that buffers position around on the screen. If you really want to get fancy, you could modify the SmartMatrix Library to allow a Layer object to accept an x,y offset, so when the refresh code calls the Layer’s fillRefreshRow() method, it can apply the offset.


Not sure if it’s helpful, but I thought about what I might do to fill the empty space on the shirt. Depending on the GIF content I might consider tiling the GIF so it appears at least partially multiple times on the screen. I might dim or blur the outside repeated tiles, like you see on portrait video content shown on a landscape video.

Unknown

I might sample the pixels and apply an Ambilight effect around the content

image

I’m not sure how practical it is to work around, but I’m actually not a fan of the “screen” look or seeing bare pixels for my LED projects. I would try to hide the panel under the shirt or a diffuser (or using the shirt material as a diffuser), so the amount of bare screen showing around smaller content wouldn’t stand out so much. The focus could be more on the content, regardless of the size, rather than the screen.

Hope that helps


#7

Gotcha, thanks for confirming that.

I may do that, thanks.

Yeah, I’ve seen that, not a fan at all :slight_smile:

I may go and do method #1 when I get around to it, it just change the way I wanted to do things, but I’ll cope :slight_smile:

Thanks for saving me time in confirming that I was going the wrong way with this.