我正在尝试使用Imager模块生成gif图像,但我收到错误
找不到对象方法“_valid_image” 无法通过包“D:\ work ... graph1.bmp”找到对象方法“_valid_image”(也许你忘了加载“D:\ work ... \ graph1.bmp”?)在C:/ Perl / site / lib / Imager.pm 1950行。
我检查了.pm文件中的模块,并在其中明确定义了命名函数。
我正在使用的代码段:
use strict;
use warnings;
use File::Find::Rule;
use Imager;
my @path = $ARGV[0];
my @images = File::Find::Rule->file()
->name( '*.bmp' )
->in( @path );
my $type = 'bmp';
foreach my $filename(@images)
{
my $img = Imager->new;
$img->read(file=>$filename, type=>$type) or die "Cannot read $filename: ", $img->errstr;
}
my $filename1 = 'ctpdbn';
Imager->write_multi({ file=>$filename1, type=>'bmp' }, @images) or die Imager->errstr;
所以我安装了Perl模块cpan Imager::valid_image
并尝试添加use Imager::valid_image;
或use Imager::_valid_image;
,但它又引发了另一个错误
无法在@INC中找到Imager / valid_image.pm(您可能需要安装Imager :: valid_image模块)(@INC 包含:C:/ Perl / site / lib C:/ Perl / lib。)at make_gif.pl第14行。
真的很抱歉没有提供完整的代码,我错过了实际出现错误的部分。现在我已经更新了
答案 0 :(得分:0)
这个错误是否真的由您向我们展示的代码生成? Imager.pm的1950行是这段代码:
my $index = 1;
for my $img (@images) {
unless ($img->_valid_image("write_multi")) { # Line 1950 here
$class->_set_error($img->errstr . " (image $index)");
return;
}
++$index;
}
这是在一个名为write_multi()
的子程序中,它作为一个(或者,实际上,我认为是几个)其参数传递@images
。你向我们展示的代码都是关于阅读文件,而不是写文件。
仔细查看错误消息,其含义很明确。它试图在图像对象上调用_valid_image()
方法。但它没有图像对象,而是有一个字符串,即图像文件名。所以似乎在某个地方,你正在调用write_multi()
传递一个图像文件名数组,你应该在其中传递一个图像对象数组。如果没有看到真正的代码,我就无法提供更多帮助。
所以我安装了Perl模块
cpan Imager::valid_image
并尝试添加use Imager::valid_image;
或use Imager::_valid_image;
那只是疯狂的谈话!错误消息非常清楚_valid_image
是方法名称,而不是模块名称。
请务必仔细阅读错误消息。有人投入了大量精力使其尽可能清晰。
更新:好的。现在您已经发布了更多代码。看起来问题就像我说的那样。这就是我昨天所说的:
所以似乎在某个地方,你正在调用
write_multi()
传递一个图像文件名数组,你应该在其中传递一组图像对象。
这是你的代码:
Imager->write_multi({ ... }, @images) or die Imager->errstr;
这里的重要变量是@images
。如何填充@images
?
my @images = File::Find::Rule->file()
->name( '*.bmp' )
->in( @path );
所以@images
包含图像文件名列表。不是图像对象列表。
看看你的主循环。
foreach my $filename(@images)
{
my $img = Imager->new;
$img->read(file=>$filename, type=>$type)
or die "Cannot read $filename: ", $img->errstr;
}
在这里循环遍历图像文件名数组,每次循环时,都会创建一个新的Imager对象。然后,当您到循环迭代结束时,将对象抛弃。这不是一个好主意。
您可能想要创建一个包含图像对象的新数组。也许是这样的事情。
@my @image_objects;
foreach my $filename(@images)
{
my $img = Imager->new;
$img->read(file=>$filename, type=>$type)
or die "Cannot read $filename: ", $img->errstr;
push @image_objects, $img;
}
然后你应该将这个新数组传递给write_multi()
。
Imager->write_multi({ ... }, @image_objects) or die Imager->errstr;
在你的辩护中,the documentation for write_multi()
并不完全清楚。它说:
<强> write_multi()强>
如果要将多个图像写入单个文件,请使用write_multi()方法:
Imager->write_multi({ file=> $filename, type=>$type }, @images) or die "Cannot write $filename: ", Imager->errstr;
但它绝不会告诉你@images
中的内容。