worstead has asked for the wisdom of the Perl Monks concerning the following question:

ImageMagick Incomplete Labeling

Given a set of images only the last label is printed

In 2003 Randal Schwartz published a program to find similar images in a file of images. His full code is to be found below. This worked well for me for several years. Then something changed in ImageMagick or Fedora's version of it. Now the line:

my $montage = $images->Montage(geometry => '400x400', label => "%p %i %wx%h %b"); print "processing...\n";

fails to place all relevant labels under the respective images. All the labels are in the file because I can print them out separately at this point in the program. Randal declined to correct the problem as he has little knowledge of Fedora.

I'm using perl-5.10.0-31.fc9.i386, ImageMagick-6.3.8.1-4.fc9.i386, and ImageMagick-perl-6.3.8.1-4.fc9.i386 under Fedora-9.

#!/usr/bin/perl -w use strict; $|++; use File::Copy qw(move); use Image::Magick; use Cache::FileCache; sub warnif; ## config my $FUZZ = 5; # permitted average deviation in the vector elements my $CORRUPT = "CORRUPT"; # if defined, rename corrupt images into this + dir ## end config my $cache = Cache::FileCache->new({ namespace => 'findimagedupes', cache_root => (glob("~/.filecache") +)[0], }); my @buckets; FILE: while (@ARGV) { my $file = shift; if (-d $file) { opendir DIR, $file or next FILE; unshift @ARGV, map { /^\./ ? () : "$file/$_"; } sort readdir DIR; next FILE; } next FILE unless -f _; my (@stat) = stat(_) or die "should not happen: $!"; my $key = "@stat[0, 1, 9]"; # dev/ino/mtime my @vector; print "$file "; if (my $data = $cache->get($key)) { print "... is cached\n"; @vector = @$data; } else { my $image = Image::Magick->new; if (my $x = $image->Read($file)) { if (defined $CORRUPT and $x =~ /corrupt|unexpected end-of-file/i +) { print "... renaming into $CORRUPT\n"; -d $CORRUPT or mkdir $CORRUPT, 0755 or die "Cannot mkdir $CORR +UPT: $!"; move $file, $CORRUPT or warn "Cannot rename: $!"; } else { print "... skipping ($x)\n"; } next FILE; } print "is ", join("x",$image->Get('width', 'height')), "\n"; warnif $image->Normalize(); warnif $image->Resize(geometry => '4x4!'); warnif $image->Set(magick => 'rgb'); @vector = unpack "C*", $image->ImageToBlob(); $cache->set($key, [@vector]); } BUCKET: for my $bucket (@buckets) { my $error = 0; INDEX: for my $index (0..$#vector) { $error += abs($bucket->[0][$index] - $vector[$index]); next BUCKET if $error > $FUZZ * @vector; } push @$bucket, $file; print "linked ", join(", ", @$bucket[1..$#$bucket]), "\n"; next FILE; } push @buckets, [[@vector], $file]; } for my $bucket (@buckets) { my @names = @$bucket; shift @names; # first element is vector next unless @names > 1; # skip unique images my $images = Image::Magick->new; $images->Read(@names); my $montage = $images->Montage(geometry => '400x400', label => "[%p] %i %wx%h %b +"); print "processing...\n"; $montage->Display(); print "Delete? [none] "; my @dead = grep { $_ >= 1 and $_ <= @$images } <STDIN> =~ /(\d+)/g; for (@dead) { my $dead_name = $images->[$_ - 1]->Get('base-filename'); warn "rm $dead_name\n"; unlink $dead_name or warn "Cannot rm $dead_name: $!"; } } use Carp qw(carp); sub warnif { my $value = shift; carp $value if $value; }

Replies are listed 'Best First'.
Re: ImageMagick Incomplete Labeling
by zentara (Cardinal) on Oct 05, 2008 at 17:52 UTC
    I can't actually run your script, but a simpler version works with the latest IM-version-6.4.3, built from source. I think its a Fedora bug. You can find the definitions on Perl-magic help

    . Why don't you build the latest IM-6.4.3 from source, and see if it works? Or run my script, and see if it works, if it does, then maybe Cache::FileCache is screwing you up.
    #!/usr/bin/perl use warnings; use strict; use Image::Magick; my $image = Image::Magick->new; umask 0022; my @pics= <*.png>; my $ok; foreach my $pic (@pics){ $ok = $image->Read($pic) and warn ($ok); } print "Montage...\n"; my $montage = $image->Montage(geometry => '300x300+8+4>', gravity=>'Center', tile=>'5x+10+200', label => "[%p] %i %wx%h %b", ); $ok = $montage->Write('montage.png') and warn ($ok);

    I'm not really a human, but I play one on earth Remember How Lucky You Are

      Tried program by zentara but does not run. Tried installing ImageMagick-6.4.3-10.tar.gz under Fedora 9 from scratch the make install failed with an error 2.

        I don't know what "error 2" is, but "make install" is throwing everything into one command, the configure, build, and install. Possibly you ran make install as a user, rather than root? Maybe you don't have the c++ devel rpm installed, etc.

        Start fresh. Unpack the tarball, then

        configure --prefix=/usr # assuming your old binaries are in /usr/bin #check for errors make #check for errors # su to root make install # now the c libs are installed # go to the PerlMagick subdir perl Makefile.PL make # su to root make install
        Report back at what step the error occurs, and what it says.

        I'm not really a human, but I play one on earth Remember How Lucky You Are