figif-core
A Rust library for GIF frame analysis and manipulation with a plugin architecture.
figif-core provides tools for:
- Duplicate Detection: Identify similar/duplicate frames using perceptual hashing
- Segment Analysis: Group consecutive similar frames into logical segments
- Timing Control: Modify frame delays to speed up, slow down, or collapse segments
- Export: Re-encode GIFs with applied modifications
Quick Start
use figif_core::prelude::*;
// Create analyzer with default settings (uses dHash)
let figif = Figif::new();
// Analyze a GIF file
let analysis = figif.analyze_file("demo.gif")?;
// Inspect detected segments
for segment in &analysis.segments {
println!(
"Segment {}: {} frames, {}ms, static={}",
segment.id,
segment.frame_count(),
segment.duration_ms(),
segment.is_static
);
}
// Cap all pause segments to max 300ms
let ops = analysis.pauses().cap(300);
// Export with a lossless encoder
let encoder = StandardEncoder::new();
analysis.export_to_file(&encoder, &ops, "output.gif", &EncodeConfig::default())?;
# Ok::<(), Box<dyn std::error::Error>>(())
Fluent Selector API
The selector API provides chainable, ergonomic control over segment operations:
use figif_core::prelude::*;
let analysis = Figif::new().analyze_file("demo.gif")?;
// Cap all pauses to 300ms
let ops = analysis.pauses().cap(300);
// Collapse only long pauses (> 500ms) to 200ms
let ops = analysis.pauses().longer_than(500).collapse(200);
// Remove pauses longer than 1 second
let ops = analysis.pauses().longer_than(1000).remove();
// Speed up motion segments by 1.5x
let ops = analysis.motion().speed_up(1.5);
// Combine operations: cap long pauses AND speed up motion
let ops = analysis.pauses().longer_than(500).cap(300)
.merge(&analysis.motion().speed_up(1.2));
// Get statistics
println!("Pause count: {}", analysis.pauses().count());
println!("Pause duration: {}ms", analysis.pauses().total_duration_ms());
# Ok::<(), Box<dyn std::error::Error>>(())
Using Different Hashers
use figif_core::{Figif, hashers::{PHasher, BlockHasher}};
// Use pHash for more robust matching
let figif = Figif::new()
.with_hasher(PHasher::new())
.similarity_threshold(8);
// Or use BlockHash
let figif = Figif::new()
.with_hasher(BlockHasher::with_size(16, 16));
Lossy Encoding (requires lossy feature)
#[cfg(feature = "lossy")]
{
use figif_core::encoders::GifskiEncoder;
use figif_core::EncodeConfig;
let encoder = GifskiEncoder::with_quality(85);
let config = EncodeConfig::new()
.with_width(480)
.with_lossy_quality(80);
let bytes = analysis.export(&encoder, &ops, &config)?;
}
Feature Flags
parallel(default): Enable parallel frame hashing using rayonlossy: Enable GifskiEncoder for high-quality lossy compression
Plugin Architecture
figif-core is designed to be extensible. You can implement custom:
- Hashers: Implement [
traits::FrameHasher] for custom duplicate detection - Decoders: Implement [
traits::GifDecoder] for custom loading - Encoders: Implement [
traits::GifEncoder] for custom output formats - Similarity Metrics: Implement [
traits::SimilarityMetric] for custom comparison