|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2016-02-28 20:59 UTC] lee dot traynor at skeptic dot de
Description: ------------ --- From manual page: http://www.php.net/imagick.getiteratorindex --- When iterating over a multi image object, getiteratorindex returns 2 "0", and all indices up to (n - 2), but not (n - 1). GetNumberImages() returns n. Also $im->current () does not return the current images, but all images. Test script: --------------- $files = array_map ("realpath", "*.JPG"); $files = array_map ("utf8_encode", $files); $im = new Imagick ($files); $im->resetIterator (); while ($im->hasNextImage ()) { echo " " . $im->getIteratorIndex (); $im->nextImage (); $im_temp = $im->current (); echo " " . $im_temp->getNumberImages (); } var_dump ($im->getNumberImages ()); Expected result: ---------------- Consecutive numbers from 0 to n - 1, interspersed with "1": 0 1 1 1 2 1 3 1 ... (n - 1) 1 (int) n Actual result: -------------- 0 n 0 n 1 n 2 n .... (n - 2) n (int) n PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Thu Oct 30 07:00:02 2025 UTC |
And a further correction: The first line of the code should read: $files = array_map ("realpath", glob ("*.JPG"));Yeah.........long story short, I recommend not using the iterator built instead just use: for ($x=0; $x<$imagick->getNumberImages(); $x++) { $imagick->setImageIndex(); //processing for particular index here. } Or if you want to extract a single image: $files = array_map ("realpath", glob ("*.jpg")); $im = new Imagick($files); $im->setIteratorIndex(1); $im_temp = $im->getImage(); $canvas = new Imagick(); $canvas->addImage($im_temp); > Also $im->current () does not return the current image, but all images. That is exactly the problem. The iterator stuff that is included in each Imagick object makes it very confusing as to whether the images are separate things that can be iterated over, or whether there is just an internal counter 'pointing' to the 'current' image. The idea of a current image is an aspect of the ImageMagick library that is best accessed via $imagick->setImageIndex() rather than an inaccurate abstraction. I'm tempted to just remove the iterator stuff.....although in theory it's a nice idea, because it doesn't actually represent what's going on internally, it's a bad abstraction, and so just leads to confusion. In practice, that would probably annoy a lot of people....so I'm holding off on doing that for now.There appears to be a subtle difference between resetIterator () and setFirstIterator (), both of which I have used interchangeably up to now. E.g. before appendImages (), combineImages (), or after morphImages (). The following modified test script works as intended with setFirstIterator (), but not with resetIterator (): $files = array_map ("realpath", glob ("*.jpg")); $files = array_map ("utf8_encode", $files); $im = new Imagick ($files); $im->setFirstIterator (); $x = 0; do { $x++; echo " " . $im->getIteratorIndex (); $im_temp[$x] = $im->getImage (); echo " " . $im_temp[$x]->getNumberImages (); } while ($im->nextImage ()); var_dump (count ($im_temp), $im->getNumberImages ()); So the question resolves to what to do with resetIterator () - I would recommend deprecating it and suggesting the use of setFirstIterator () instead. In the end for me it was much easier to load the images into an array and work with arrays. Ta.