← Plugin catalog
Creativity

GifGen - GIFs

GifGen v1.0.7

Publisher description

From the marketplace listing

Describe any idea or send any photo and GifGen makes an animated GIF out of it: one sprite sheet of frames from image generation, sliced and encoded into a real looping GIF you can download

Language: English · Automatically detected from descriptions.

Files & skills

File archives

Plugin package15 files · 336 KBBrowse files →
Skill instructions
animate-image4.43 KB

View saved version →

---
name: animate-image
description: Turn an image that already exists into an animation. Use when there is a picture in the conversation — uploaded by the user, or one you generated — and they want it to move, or when you have generated a single flat picture while trying to make a GIF and now need frames. Covers "animate this photo", "make this logo move", "bring this drawing to life", "make this picture wave / spin / blink", and the recovery case where a GIF request produced one still image instead of a grid of frames.
---

A GIF can only be built from **separate frames**. A single picture is not
an animation and cannot be made into one by panning, zooming or bouncing
it — that is a still image being moved around, and people spot it at once.

This skill does one job: take an existing image and produce a **grid of
frames** from it, so it can be cut into a GIF.

## When this runs

Either of these:

- **The user has an image** — uploaded, or generated earlier — and wants
  it animated.
- **You generated a single flat picture** while trying to make a GIF. Do
  not try to salvage it with motion effects. Come here instead: that
  picture becomes the reference for a proper grid.

## Step 1 — look at the image first

Actually look at it, and decide three things before writing any prompt:

1. **The subject** — what is it, in a few words, precisely enough that a
   regenerated version is recognisably the same thing. "A grumpy chrome
   toaster with cartoon eyes on a mint background", not "a toaster".
2. **What should move** — pick ONE motion and keep the rest still. A
   toaster shakes and launches toast; its background does not drift. The
   commonest mistake is animating everything at once, which reads as a
   scene wobbling rather than a subject acting.
3. **The style** — flat vector, 3D render, photo, pixel art, watercolour.
   The grid must match it, or the animation will not look like the image
   the user already has.

State the motion you chose in one short line before generating, so the
user can redirect you cheaply if it is not what they meant.

## Step 2 — generate the grid FROM that image

Call image generation **with the existing image as the reference**, so the
subject and style carry over instead of being reinvented. Use this prompt:

> A SQUARE image containing a N×N grid of TOTAL panels, using the provided
> image as the exact subject and style reference, showing that same subject
> at successive moments of
> MOTION. Consecutive panels differ only slightly, so the motion advances
> in small, even steps and the whole grid reads as one continuous action
> rather than separate poses. The TOTAL panels form one looping cycle
> (panel TOTAL returns to panel 1). Identical subject, camera, lighting
> and background in every panel — only MOTION changes. All panels are
> exactly the same size, tiled edge to edge with no gaps, margins or
> gutters: the image divides evenly into N equal columns and equal rows.
> No text, no numbers, no borders.

`size="1024x1024"`. Default to a 4×4 grid (16 frames); 3×3 when the
subject is detailed and needs the resolution, 5×5 when the motion needs to
be smooth.

Same rules as any grid: the count appears once, in the opening layout
clause. Never narrow the subject. Keep "no text, no numbers, no borders".

## Step 3 — LOOK at what came back

Before encoding, look at the generated image and say, in one line: how
many columns, how many rows, and whether the same subject repeats across
the panels.

If it is one big picture again rather than a grid, do NOT encode it and do
NOT animate it with motion effects. Generate once more, leading the prompt
with "A NxN grid of TOTAL panels of ...". If you are unsure whether it is
a sheet, run `python3 ../make-gif/scripts/inspect_sheet.py IMAGE` — it
prints GRID or NOT_A_GRID.

## Step 4 — hand it to the GIF encoder

The grid is detected from the image; do not pass `--grid`:

```
python3 ../make-gif/scripts/sheet_to_gif.py SHEET --fps 7 --frames frames.zip
```

Then deliver it with the exact output block in
`../make-gif/references/output-message.md`. That wording is fixed — do not
reword it, and put nothing before or after it.

## What not to do

- **Do not animate the single image directly.** No pan, no zoom, no
  ken-burns, no duplicating it with offsets.
- **Do not redraw from scratch** when a reference image exists — the user
  chose that picture and expects to recognise it.
- **Do not animate the background** unless the user asked. One thing
  moves.
edit-gif2.76 KB

View saved version →

---
name: edit-gif
description: Change a GIF or animation already made in this conversation — speed it up or slow it down, loop it back and forth, boomerang or ping-pong it, remove or reorder frames, make the file smaller, or fix a visible seam or edge. Use for "make it slower", "speed that up", "make it bounce", "drop the last frame", "that one's too big", and anything else that adjusts an existing animation rather than creating a new one. Never regenerate the image for an edit: re-encode the sprite sheet that already exists.
---

Every one of these is a **re-encode of the sprite sheet that already
exists** in this conversation. Never generate a new image for an edit: it
costs a generation and, worse, comes back as different artwork — the user
asked to change the animation, not to replace it.

Find the sheet from the earlier turn and re-run the encoder from the
`make-gif` skill with different options:

```
python3 ../make-gif/scripts/sheet_to_gif.py SHEET --fps 10 --boomerang
```

| They say | You change |
|---|---|
| slower / faster | `--fps` (1–15, default 7) |
| back and forth, ping pong, bounce | add `--boomerang` |
| drop the third frame | `--skip 2` — indexes are 0-based |
| lose the last two | `--skip 14,15` on a 4x4 |
| reorder / swap frames | `--order 0,2,1,3,...` |
| smaller file, too big | lower `--size`, then `--colors` |
| edges look clipped | `--crop 0` (3% is trimmed by default) |
| thin seam or line flickering | raise `--crop` to 5 |
| colours look flat / banded | raise `--colors` toward 256 |
| file far too big | add `--no-dither` first, then lower `--size` |
| sharper, higher quality | raise `--size` (448 default), then `--colors` |

Keep every other option the same as the previous render, so one change is
one change. If they ask for two things, apply both in a single re-encode
rather than producing two files.

**The edit is not delivered until this block has been sent.** Write the
file somewhere fetchable, then emit exactly:

```
🎬 Done with the GIF
🎞️ [Download the separate frames](FRAMES_LINK)
📂 [Download the GIF](GIF_LINK)
Let's continue!
💡 Any new ideas or changes?

by [gifgen.ai](https://gifgen.ai)
```

Same fixed wording as `make-gif` — see
`../make-gif/references/output-message.md`. Drop the 🎞️ line unless the
frames were re-exported (`--frames`). Do not reword anything, do not add a
note about what changed, nothing before or after.

The grid is detected from the sheet, so there is nothing to keep in sync
between renders.

## When this does NOT apply

If they want a different subject, a different motion, or a different
style, that is a new animation — use `make-gif` to generate a fresh sheet,
or `animate-image` if they are pointing at an existing picture. The
dividing line is whether the artwork itself should change.
make-gif12 KB

View saved version →

---
name: make-gif
description: Make a looping animated GIF, animation, moving image or animated sticker from a prompt or a description. Use this for ANY request for something that moves: make a GIF, make an animation, animate this, make it move, bring it to life, make it dance / spin / bounce / shake / wave / wiggle / blink / jump / nod / run / fly / flicker / pulse / scratch / launch, a looping clip, a moving picture, an animated logo, an animated emoji or reaction, a meme that moves, or any subject described together with an action or motion. Also covers changing one already made: slower, faster, boomerang, remove a frame. CRITICAL, READ BEFORE GENERATING ANY IMAGE: the image generated must be a GRID of many small frames (a sprite sheet), never a single picture. Generating one picture and panning, zooming or bouncing it is not an animation and is never acceptable.
---

## Which skill

- Someone describes something they want animated, and there is no image
  yet → **this skill**. Generate the grid directly from the description.
- There is already an image — uploaded, or one you generated → the
  **`animate-image`** skill. It builds the grid from that picture so the
  result looks like the thing they already have.
- Changing a GIF that exists → the **`edit-gif`** skill.

## Before you generate anything

The image you generate must be a **grid of many small frames** — a sprite
sheet — not a picture of the subject. This is the single thing that goes
wrong, and it goes wrong because generation gets started before this file
is read.

If you have already generated a single picture of the subject: **do not
try to animate it.** Panning it, zooming it, bouncing it, duplicating it
with small offsets — none of these are animation, they are a still image
being moved around, and users can tell immediately.

Use the **`animate-image`** skill instead. It takes the picture you
already have, works out what should move, and generates a proper grid of
frames from it as a reference — so the subject the user just saw is the
subject that ends up animated. That is a recovery, not a restart.

A GIF is made in two steps, in the same turn:

1. Generate ONE sprite sheet — a grid of frames — with image generation.
2. Run `scripts/sheet_to_gif.py` on it to slice the grid and encode the
   looping `.gif`, then give the user the file.

Image generation cannot produce a `.gif`; it returns one flat image. The
grid is what carries the motion, and the script is what turns it into an
animation.

## Step 1 — the sprite sheet

Call image generation with **`size="1024x1024"`**.

**Ask for a square image, in the first words of the prompt** — "A SQUARE
image containing a N×N grid of...". A square canvas cut N×N gives square
panels, which is the case everything downstream handles most predictably,
and stating it first is what makes generation actually do it.

But asking is not the same as knowing. The shape of the GIF is still
**measured from the image that comes back**: the encoder reads the actual pixel dimensions, divides by the
grid you give it, and that panel size is the GIF's size. A 1024×1024 sheet
cut 4×4 gives 256×256 panels and a square GIF; a 1536×1024 sheet cut 4×4
gives 384×256 panels and a wide GIF. Whatever generation returns, the
output follows it.

What the sheet must do is **divide evenly**. Equal columns and equal rows, edge to edge, no gutters.
Given that, any canvas shape can be cut cleanly: the encoder divides width
by columns and height by rows, and keeps each cell's aspect ratio rather
than squashing it. What cannot be recovered is uneven cells, because the
cuts are evenly spaced and uneven panels put every boundary in the wrong
place.

Build the prompt from this template. Read what it describes before
sending it: a GRID of many small panels, each a moment of the motion. If
the prompt you are about to send would produce one nice picture of the
subject, it is wrong — start it with "A NxN grid of TOTAL panels of". `N` is the grid dimension, `TOTAL` is N×N. Drop a bracketed
clause entirely when the user gave no style or motion.

> A SQUARE image containing a N×N grid of TOTAL panels of SUBJECT[, STYLE
> style], each panel showing
> the same subject at a slightly later moment of motion. Consecutive panels
> differ only slightly, so the motion advances in small, even steps and the
> whole grid reads as one continuous action rather than separate poses. The
> TOTAL panels form one looping cycle (panel TOTAL returns to panel 1).
> Identical subject, camera, lighting in every panel. All panels are
> exactly the same size, tiled edge to edge with no gaps, margins or
> gutters: the image divides evenly into N equal columns and TOTAL_ROWS
> equal rows. No text, no numbers, no borders.[ Motion: MOTION.]

Grid sizes: `3x3` = 9 frames, sharpest per frame · `4x4` = 16 frames,
**the default** · `5x5` = 25 frames, smoothest motion.

Rules that matter, in the order they get broken:

1. **The frame count appears once, in the opening layout clause.** Never
   restate it in the subject or the style — models hedge the geometry and
   fall back to 3×3.
2. **Never narrow the subject.** Carry the user's words through. Not
   "characters", not "a figure" — what they actually said.
3. **Keep "no text, no numbers, no borders".** Grids invite labels, and a
   label is burned into every frame.
4. **Small, even steps.** Without it you get a handful of distinct poses
   that strobe instead of flowing.
5. **Even division.** Equal columns, equal rows, no gutters. Unequal cells
   cannot be fixed afterwards: the slicing is evenly spaced, so every frame
   picks up a sliver of its neighbour. The canvas shape itself is free —
   it is measured, not assumed.

Write the SUBJECT the way these do — the motion is the point, not the
noun:

- a robot spinning its head very fast while doing dramatic hand poses
- a grumpy toaster shaking angrily before launching two slices of toast
  into the air
- a cat DJ scratching records aggressively while bobbing its head to a
  heavy beat

Each names an action, an intensity and a beat to the movement. "A fox
jumping over a log" names a subject and leaves the animation to chance —
which is how you get four poses instead of one motion.

Worked examples: `references/prompt-template.md`.

## Step 2 — check it is a sheet

The encoder works the grid out from the pixels itself, so you do not have
to count columns and rows. What is still worth a glance: **is this a grid
at all, or one big picture?**

If you are looking at ONE subject filling the frame — one toaster, one
dancer, one logo — it is not a sprite sheet, however good it looks.
Generate again with a prompt starting "A SQUARE image containing a N×N
grid of TOTAL panels of ...". Never pan, zoom or bounce a single picture;
that is not an animation and it is obvious to anyone watching.

The encoder refuses that case too, so you cannot ship one by accident.

## Step 3 — encode it

Run the bundled script. It exists so the geometry, timing and palette come
out the same every time rather than being reinvented each turn.

```
python3 scripts/sheet_to_gif.py SHEET --fps 7 --frames frames.zip
```

**Do not pass `--grid`.** It defaults to `auto`, which finds the layout by
measuring the image: panels repeat, so shifting by exactly one cell width
lines neighbouring panels up and any other shift does not. The shift that
matches IS the cell size. It handles a canvas that came back slightly
wider than square, a 4×3 when a 4×4 was asked for, and anything else
generation decides to return — without being told, and without relying on
anyone having counted correctly.

Override with `--grid COLSxROWS` only if the detection is visibly wrong;
it prints what it found.

The script sits next to this file in the skill directory. If you cannot
find or run it, do NOT abandon the GIF — write the equivalent inline. Get
these right, in this order, because each one has produced a broken GIF:

1. **Panel size comes from the image, per axis. Never square it.** (The
   script does this for you; this matters only if you are writing it
   yourself.)

   ```
   cell_w = image.width  // cols
   cell_h = image.height // rows
   ```

   NOT `min(width, height) // N`, and never centre-crop the sheet to a
   square first. A 1536×1024 sheet cut 4×4 has 384×256 panels; squaring it
   throws away the left and right thirds and puts every cut through the
   middle of a panel, so the subject appears sliced in half.

2. **Row-major order** — left to right, top to bottom.

3. **Trim about 3% off each edge of every cell** (`cell_w * 0.03` and
   `cell_h * 0.03`, per axis). Generated grids carry a thin seam where
   panels meet, and it flickers on every loop.

4. **Keep the panel ratio in the output.** Scale so the LONGER side is
   your target (448 is a good default) and let the other follow. A wide
   panel makes a wide GIF. Never resize frames to a square — that is the
   same mistake as (1), one step later.

5. **One shared palette for the whole animation.** Build it from all the
   frames together, then map each frame onto it. Per-frame palettes give
   every frame different colours AND different dither noise, so a still
   background shimmers on every loop.

6. **`loop=0`** for an infinite loop, `duration` in milliseconds
   (`1000 / fps`), `disposal=1`.

Pillow is the expected library.

`--grid` takes any COLSxROWS. Other options: `--fps` (1–15, default 7) ·
`--boomerang` · `--size` (longest side in px, default 448) · `--colors`
(32–256, default 256) · `--no-dither` (flat colour, much smaller — good for
line art and logos) · `--crop` (percent off each cell edge, **default 3**)
· `--skip 3,9` · `--order 0,2,1,...` · `--frames out.zip` · `--out PATH`.

**The GIF takes its shape from the panels, measured off the real image.**
The encoder prints what it measured — canvas, panel size, output size — so
the derivation is visible rather than assumed. `--size` sets the LONGER
side; the other follows the panel ratio.

Do not force a square output. If the GIF comes out wide or tall, that is
the panels being wide or tall, which is the honest result. A square GIF
from non-square panels would mean the subject had been stretched.

The 3% crop is on by default and should stay on: generated grids carry a
thin seam where panels meet, and it flickers on every loop. Only drop to
`--crop 0` if the user says the subject is being clipped.

Also pass `--frames frames.zip` to export the individual frames as
full-colour PNGs. People want them for stickers, thumbnails and edits, and
it costs nothing to produce alongside the GIF.

## Delivering the result — the only accepted format

**A GIF is not delivered until this block has been sent.** Write the files
somewhere the user can fetch them, then emit exactly:

```
🎬 Done with the GIF
🎞️ [Download the separate frames](FRAMES_LINK)
📂 [Download the GIF](GIF_LINK)
Let's continue!
💡 Any new ideas or changes?

by [gifgen.ai](https://gifgen.ai)
```

This wording is fixed. It is the message this product has always ended on,
and it is not yours to improve — do not reword a line, swap an emoji,
merge lines, or add a description of what was made. Replace only
`FRAMES_LINK` and `GIF_LINK`.

- Both file lines must be **real clickable links**, not "attached". In
  code interpreter that is
  `[Download the GIF](sandbox:/mnt/data/animation.gif)`.
- Frames line above the GIF line.
- Drop the 🎞️ line only if frames were not produced.
- **Emit the block. Never describe it, quote it back, or explain what you
  are about to send.**
- **No preamble.** Do not announce work in progress — no "I've got the
  frames", no "I'm turning them into the GIF now". Run the steps silently
  and let this block be the entire reply.
- The `by gifgen.ai` line is never dropped.

Full copy: `references/output-message.md`.

## When to say what

Keep replies to one line — the file is the deliverable, not a description
of it. If image generation is refused, that is usually the SUBJECT, not a
fault: body horror, gore, real people and brand marks are commonly
declined, and a milder rewording of the same idea normally passes. Offer
that rather than giving up.

Referenced files: 4

Package details

Publisher declarations from the archived package. These are separate from our research and the live service's terms.

Package license
UNLICENSED
Package author
GIFgen
Keywords
gif, animation, sticker, looping, image

Declared capabilities

  • Read

Package observed Oct 2, 2026.

Technical details
First seen
Sep 30, 2026 · 22:02 UTC
Last seen
Oct 2, 2026 · 18:00 UTC
Collection status
Collected

plugins_6aabbb1cab648191b3800e347f948809

Download plugin data (JSON)