Convert Figma logo to code with AI

ImageOptim logogifski

GIF encoder based on libimagequant (pngquant). Squeezes maximum possible quality from the awful GIF format.

4,715
136
4,715
24

Top Related Projects

Lossy PNG compressor — pngquant command based on libimagequant library

GUI image optimizer for Mac

45,445

Mirror of https://git.ffmpeg.org/ffmpeg.git

Quick Overview

Gifski is a high-quality GIF encoder written in Rust. It converts video frames to GIF animations using pngquant's efficient cross-frame palettes and temporal dithering. This results in smaller file sizes and higher quality compared to traditional GIF encoders.

Pros

  • High-quality GIF output with efficient compression
  • Fast encoding due to Rust implementation
  • Supports a wide range of input formats
  • Cross-platform compatibility (Windows, macOS, Linux)

Cons

  • Limited to GIF output format only
  • May require more processing power for complex animations
  • Lacks advanced features like text overlays or filters

Code Examples

  1. Basic GIF creation from a video file:
use gifski::{progress, Collector, Settings};
use std::fs::File;

let (collector, writer) = Collector::new(Settings::default(), 1920, 1080);
let mut file = File::create("output.gif").unwrap();
let mut encoder = writer.write(&mut file, &progress::NoProgress {});

// Add frames from video file
// ...

encoder.finish().unwrap();
  1. Creating a GIF with custom settings:
use gifski::{Repeat, Settings};

let settings = Settings {
    width: Some(800),
    height: Some(600),
    quality: 90,
    fast: false,
    repeat: Repeat::Infinite,
};

let (collector, writer) = Collector::new(settings, 1920, 1080);
// Continue with GIF creation process
  1. Adding frames to the GIF:
use gifski::Collector;
use rgb::RGBA8;

let (mut collector, writer) = Collector::new(Settings::default(), 1920, 1080);

for (i, frame) in frames.iter().enumerate() {
    let pixels: Vec<RGBA8> = frame.to_rgba();
    collector.add_frame_rgba(i, &pixels, 1920, 1080, 100).unwrap();
}

Getting Started

To use Gifski in your Rust project, add the following to your Cargo.toml:

[dependencies]
gifski = "1.10.0"

Then, in your Rust code:

use gifski::{progress, Collector, Settings};
use std::fs::File;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let (collector, writer) = Collector::new(Settings::default(), 1920, 1080);
    let mut file = File::create("output.gif")?;
    let mut encoder = writer.write(&mut file, &progress::NoProgress {})?;

    // Add frames here

    encoder.finish()?;
    Ok(())
}

This sets up a basic GIF encoder. You'll need to add frames to the collector based on your specific use case.

Competitor Comparisons

Lossy PNG compressor — pngquant command based on libimagequant library

Pros of pngquant

  • Specializes in PNG optimization, offering excellent compression for PNG files
  • Supports color palette reduction while maintaining visual quality
  • Widely used and well-established tool with extensive documentation

Cons of pngquant

  • Limited to PNG format, while gifski supports GIF creation and optimization
  • May not be as effective for animated images compared to gifski's capabilities
  • Lacks some of the advanced features for creating high-quality GIFs that gifski offers

Code Comparison

pngquant:

pub fn compress(input: &[u8], quality: u8) -> Result<Vec<u8>, Error> {
    let mut liq = Attributes::new();
    liq.set_quality(0, quality);
    let img = liq.new_image(&input, width, height, 0.0)?;
    // ... (compression logic)
}

gifski:

pub fn encode(frames: &[Frame], width: u32, height: u32, fps: f32) -> Result<Vec<u8>, Error> {
    let mut gif = Gif::new(width, height);
    gif.set_repeat(Repeat::Infinite);
    for frame in frames {
        gif.push_frame(&frame.pixels, frame.delay, fps)?;
    }
    // ... (encoding logic)
}

Both projects use Rust for efficient image processing, but their focus differs. pngquant specializes in PNG optimization, while gifski excels in creating high-quality GIFs from video frames or image sequences.

GUI image optimizer for Mac

Pros of ImageOptim

  • Supports a wide range of image formats (JPEG, PNG, GIF, etc.)
  • Provides a user-friendly GUI for easy image optimization
  • Integrates multiple optimization tools and algorithms

Cons of ImageOptim

  • Limited to image optimization tasks only
  • May have slower processing times for large batches of images
  • Less specialized in GIF optimization compared to Gifski

Code Comparison

ImageOptim (Objective-C):

- (void)optimizeFile:(NSString *)file {
    NSTask *task = [[NSTask alloc] init];
    [task setLaunchPath:@"/usr/local/bin/optipng"];
    [task setArguments:@[@"-o2", file]];
    [task launch];
}

Gifski (Rust):

pub fn encode(frames: &[Frame], width: u32, height: u32, repeat: u32) -> Result<Vec<u8>, Error> {
    let mut gif = Gif::new(width, height);
    gif.set_repeat(repeat);
    for frame in frames {
        gif.push_frame(&frame)?;
    }
    gif.finish()
}

Summary

ImageOptim is a versatile image optimization tool with a GUI, supporting various formats. Gifski, on the other hand, is specialized in high-quality GIF creation from video files. While ImageOptim offers broader functionality, Gifski excels in its specific niche of GIF encoding.

45,445

Mirror of https://git.ffmpeg.org/ffmpeg.git

Pros of FFmpeg

  • Comprehensive multimedia framework supporting a wide range of formats and codecs
  • Extensive command-line options for advanced video/audio processing
  • Large community and extensive documentation

Cons of FFmpeg

  • Steeper learning curve due to its complexity
  • Larger file size and resource requirements

Code Comparison

FFmpeg (converting video to GIF):

ffmpeg -i input.mp4 -vf "fps=10,scale=320:-1:flags=lanczos" output.gif

Gifski (converting video to GIF):

gifski -o output.gif input.mp4

Summary

FFmpeg is a powerful, versatile multimedia framework supporting numerous formats and offering extensive processing capabilities. It excels in complex video and audio tasks but may be overwhelming for simple operations.

Gifski, on the other hand, is specialized for creating high-quality GIFs from video sources. It's simpler to use and optimized for this specific task, making it more accessible for users primarily interested in GIF creation.

While FFmpeg provides greater flexibility and broader functionality, Gifski offers a streamlined solution for high-quality GIF conversion. The choice between the two depends on the user's specific needs and technical expertise.

Pros of FFmpeg-Builds

  • Broader functionality: FFmpeg-Builds provides a comprehensive suite of multimedia tools for encoding, decoding, and manipulating various audio and video formats
  • Extensive platform support: Offers builds for multiple operating systems and architectures
  • Active development and frequent updates

Cons of FFmpeg-Builds

  • Higher complexity: Requires more technical knowledge to use effectively compared to Gifski's focused approach
  • Larger file size: The full FFmpeg package is significantly larger than Gifski
  • Potentially overwhelming for users who only need GIF-specific functionality

Code Comparison

Gifski (Rust):

let mut encoder = Encoder::new(output_path, width, height, repeat)?;
encoder.set_quality(quality);
encoder.write_frame(&frame, frame_number)?;

FFmpeg-Builds (C):

AVCodecContext *c = avcodec_alloc_context3(codec);
c->width = width;
c->height = height;
avcodec_open2(c, codec, NULL);
av_frame_make_writable(frame);

Both repositories serve different purposes. Gifski focuses specifically on high-quality GIF creation, while FFmpeg-Builds provides a comprehensive multimedia toolkit. The choice between them depends on the user's specific needs and technical expertise.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

gif.ski

Highest-quality GIF encoder based on pngquant.

gifski converts video frames to GIF animations using pngquant's fancy features for efficient cross-frame palettes and temporal dithering. It produces animated GIFs that use thousands of colors per frame.

(CC) Blender Foundation | gooseberry.blender.org

It's a CLI tool, but it can also be compiled as a C library for seamless use in other apps.

Download and install

See releases page for executables.

If you have Homebrew, you can also get it with brew install gifski.

If you have Rust from rustup (1.63+), you can also build it from source with cargo install gifski.

Usage

gifski is a command-line tool. If you're not comfortable with a terminal, try the GUI version for Windows or for macOS.

From ffmpeg video

Tip: Instead of typing file paths, you can drag'n'drop files into the terminal window!

If you have ffmpeg installed, you can use it to stream a video directly to the gifski command by adding -f yuv4mpegpipe to ffmpeg's arguments:

ffmpeg -i video.mp4 -f yuv4mpegpipe - | gifski -o anim.gif -

Replace "video.mp4" in the above code with actual path to your video.

Note that there's - at the end of the command. This tells gifski to read from standard input. Reading a .y4m file from disk would work too, but these files are huge.

gifski may automatically downsize the video if it has resolution too high for a GIF. Use --width=1280 if you can tolerate getting huge file sizes.

From PNG frames

A directory full of PNG frames can be used as an input too. You can export them from any animation software. If you have ffmpeg installed, you can also export frames with it:

ffmpeg -i video.webm frame%04d.png

and then make the GIF from the frames:

gifski -o anim.gif frame*.png

Note that * is a special wildcard character, and it won't work when placed inside quoted string ("*").

You can also resize frames (with -W <width in pixels> option). If the input was ever encoded using a lossy video codec it's recommended to at least halve size of the frames to hide compression artefacts and counter chroma subsampling that was done by the video codec.

See gifski --help for more options.

Tips for smaller GIF files

Expect to lose a lot of quality for little gain. GIF just isn't that good at compressing, no matter how much you compromise.

  • Use --width and --height to make the animation smaller. This makes the biggest difference.
  • Add --quality=80 (or a lower number) to lower overall quality. You can fine-tune the quality with:
    • --lossy-quality=60 lower values make animations noisier/grainy, but reduce file sizes.
    • --motion-quality=60 lower values cause smearing or banding in frames with motion, but reduce file sizes.

If you need to make a GIF that fits a predefined file size, you have to experiment with different sizes and quality settings. The command line tool will display estimated total file size during compression, but keep in mind that the estimate is very imprecise.

Building

  1. Install Rust via rustup. This project only supports up-to-date versions of Rust. You may get errors about "unstable" features if your compiler version is too old. Run rustup update.
  2. Clone the repository: git clone https://github.com/ImageOptim/gifski
  3. In the cloned directory, run: cargo build --release. This will build in ./target/release.

Using from C

See gifski.h for the C API. To build the library, run:

rustup update
cargo build --release

and link with target/release/libgifski.a. Please observe the LICENSE.

C dynamic library for package maintainers

The build process uses cargo-c for building the dynamic library correctly and generating the pkg-config file.

rustup update
cargo install cargo-c
# build
cargo cbuild --prefix=/usr --release
# install
cargo cinstall --prefix=/usr --release --destdir=pkgroot

The cbuild command can be omitted, since cinstall will trigger a build if it hasn't been done already.

License

AGPL 3 or later. I can offer alternative licensing options, including commercial licenses. Let me know if you'd like to use it in a product incompatible with this license.

With built-in video support

The tool optionally supports decoding video directly, but unfortunately it relies on ffmpeg 6.x, which may be very hard to get working, so it's not enabled by default.

You must have ffmpeg and libclang installed, both with their C headers installed in default system include paths. Details depend on the platform and version, but you usually need to install packages such as libavformat-dev, libavfilter-dev, libavdevice-dev, libclang-dev, clang. Please note that installation of these dependencies may be quite difficult. Especially on macOS and Windows it takes expert knowledge to just get them installed without wasting several hours on endless stupid installation and compilation errors, which I can't help with. If you're cross-compiling, try uncommenting [patch.crates-io] section at the end of Cargo.toml, which includes some experimental fixes for ffmpeg.

Once you have dependencies installed, compile with cargo build --release --features=video or cargo build --release --features=video-static.

When compiled with video support ffmpeg licenses apply. You may need to have a patent license to use H.264/H.265 video (I recommend using VP9/WebM instead).

gifski -o out.gif video.mp4

Cross-compilation for iOS

The easy option is to use the included gifski.xcodeproj file to build the library automatically for all Apple platforms. Add it as a subproject to your Xcode project, and link with gifski-staticlib Xcode target. See the GUI app for an example how to integrate the library.

Cross-compilation for iOS manually

Make sure you have Rust installed via rustup. Run once:

rustup target add aarch64-apple-ios

and then to build the library:

rustup update
cargo build --lib --release --target=aarch64-apple-ios

The build may print "dropping unsupported crate type cdylib" warning. This is expected when building for iOS.

This will create a static library in ./target/aarch64-apple-ios/release/libgifski.a. You can add this library to your Xcode project. See gifski.app for an example how to use libgifski from Swift.