Open captainviet opened 6 years ago
The color map maps the raw pixel values (0–255) onto rgb triplets. Frame::from_rgba
will solve this for you.
This will make the image considerably larger as it then uses a local color map for every frame one strategy would be to extract the color map from the first frame and use it as a global color map. And create the successive frames like you did.
Hi @nwin ,
Actually my first attempt was using Frame::from_rgba
. The reason I try to find an alternative is because the performance of this method is terrible: 2 minutes to convert each JPEG images to a frame.
Regarding the color map, I don't know what it is in the first place, so I've searched the documentation but I cannot find any method to get that property. I may have missed something, so for clarification is there anyway to extract the color map from an RgbaImage
or similar entities?
Actually my first attempt was using Frame::from_rgba. The reason I try to find an alternative is because the performance of this method is terrible: 2 minutes to convert each JPEG images to a frame.
Encoding performance of lzw
, the current implementation of LZW encoding, was terrible. It's going to be much faster with the next release where that implementation is switched.
BTW, the performance bottleneck is not in LZW, but in color_quant
. This algorithm (neuquant) performs quite a lot of work per pixel. You could use another quantization algorithm, e.g. imagequant
that is faster (mediancut scales sub-linearly with number of unique colors).
Hi,
I'm new to Rust, yet I need to write a piece of Rust code to create a GIF file from a series of JPEG screenshots.
Currently my generated GIF is glitchy, the content seems enlarged and the colors don't look right. I'm wondering whether this is related to the compatibility of JPEG as frames for GIF, or because I'm using the wrong palette for the
GIF Encoder
? I'm learning so comments are welcome! Thanks in advance!A brief summary for the code below:
screenshot()
returns animage::RgbaImage
width
andheight
of each of the image (and the derivedFrame
) is fixedcolor_map
is set to[ FF, FF, FF, FF, 00, 00 ]
(which I supposed is R, G, B, and A enabled? Pardon me as I cannot find any reference to the palette parameter)use image as im; use std::fs::File; use std::thread; use std::time::Duration; use time::PreciseTime as tpt; use gif::{Frame, Encoder, Repeat, SetParameter}; use std::borrow::Cow; use screenshot::screenshot;
fn main() { let mut image = File::create("sample.gif").unwrap(); let img: im::RgbaImage = screenshot(); println!("Len: {}", img.len()); println!("Original: {}x{}", img.width(), img.height()); let width: u16 = img.width() as u16; let height: u16 = img.height() as u16; println!("Compressed: {}x{}", width, height); let color_map = &[0xFF, 0xFF, 0xFF, 0xFF, 0, 0]; let mut encoder = Encoder::new(&mut image, width, height, color_map).unwrap(); encoder.set(Repeat::Infinite).unwrap(); for i in 0..6 { let start = tpt::now(); let img: im::RgbaImage = screenshot(); let mid1 = tpt::now(); println!("Getting raw buffer..."); let pixes: &mut [u8] = &mut img.into_raw(); println!("Getting frame..."); //let mut frame = Frame::from_rgba(width, height, pixes); let mut frame = Frame::default(); frame.width = width; frame.height = height; frame.buffer = Cow::Borrowed(pixes); println!("Writing frame..."); encoder.write_frame(&frame).unwrap(); let end = tpt::now(); println!("Duration: {} {}", start.to(mid1).num_milliseconds(), mid1.to(end).num_milliseconds()); } }