Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better Support for Image Lists #30

Open
jhwgh1968 opened this issue Nov 30, 2017 · 1 comment
Open

Better Support for Image Lists #30

jhwgh1968 opened this issue Nov 30, 2017 · 1 comment

Comments

@jhwgh1968
Copy link

jhwgh1968 commented Nov 30, 2017

The MagickWand API supports image lists. For example, opening a GIF animation puts each frame into a list attached to that wand. List items can be deleted, edited individually, and even composited into a single image.

Looking through the code, this seems partially supported, but difficult to use. A caller would have to manually manipulate the wand's image iterator with getters and setters without any external state consistency. (One function could change the iterator's position and not clean it up before another unrelated call, resulting in unexpected outcomes.)

It would be nice if the internal iterator could be borrowed and reset automatically, more like this:

let w = MagickWand::new(...);
w.read_image("input.gif")?
{
    let last_frame = w.images().last(); // moves the iterator to the last image and returns a borrow
    let also_last_frame = w.images().index(w.images().count()); // same as above
    let last_dim = last_frame.get_image_size(); // this != the frame size for an optimized GIF
    println!("The last image is {} pixels wide and {} pixels high", last_dim.0, last_dim.1);
}
{
    // Make a message appear for one frame
    let first_frame = w.images_mut().first(); // same construction as above, but returns mutable borrows
    let draw = DrawingWand::new()?
    draw.set_size(12)?
    draw.draw_annotation("Behold!", 0, 0)?
    first_frame.draw_image(draw)?
}
// Now make a second message scroll down the image
let (ww, wh, wx, wy) = w.get_image_page();
let nframes = w.images().count();
for (n, &mut frame) in w.images_mut().enumerate() {
    let draw = DrawingWand::new()?
    draw.set_size(12)?
    draw.draw_annotation("Moving text", 0, ((wh as f32) * (n as f32) / (nframes as f32)) / 2)?
    frame.draw_image(draw)?
}

// We're done, write it out
w.write_image("output.gif")?

EDIT: fixed a bug in my example code

@nlfiedler
Copy link
Owner

I'm in favor of that, but my Rust skills have deteriorated since the time I started this project, so it's unlikely I'll be able to make a change. I welcome any pull requests, as always.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants