是什么原因导致Imager类的scaleX方法失败?

时间:2009-07-29 03:16:37

标签: database perl image

这是来自Perl Monks和Mahalo答案的交叉帖子,我还没有收到满意的答复。感谢您的时间和精神:

为什么我从perl收到此错误消息:

Can't call method "scaleY" on an undefined value at C:/strawberry/perl +/site/lib/ Image/Seek.pm line 137?

从我的脚本调用Image :: Seek模块时,我在标题中收到错误。我的脚本基本上是对模块建议代码的重复。

这是错误:

Can't call method "scaleY" on an undefined value at C:/strawberry/perl +/site/lib/ Image/Seek.pm line 137.

这是我的代码:

#!/usr/local/bin/perl 
use Imager;
use Image::Seek qw(loaddb add_image query_id savedb);

loaddb("haar.db");
my $img = Imager->new("photo-1.jpg")
or  die Imager->errstr;

# my $img = Imager->new();
# $img->open(file => "photo-1.jpg")or die Imager->errstr;

add_image($img, 1);
savedb("haar.db");

以下是导致问题的Image :: Seek模块部分:

sub add_image_imager {
    my ($img, $id) = @_;
    my ($reds, $blues, $greens);
    require Imager;
    my $thumb = $img->scaleX(pixels => 128)->scaleY(pixels => 128);
    for my $y (0..127) {
        my @cols = $thumb->getscanline(y => $y);
        for (@cols) {
            my ($r, $g, $b) = $_->rgba;
            $reds .= chr($r); $blues .= chr($b); $greens .= chr($g);
        }
    }
    addImage($id, $reds, $greens, $blues); }

第137行是:

my $thumb = $img->scaleX(pixels => 128)->scaleY(pixels => 128);

如果我删除

->scaleY(pixels => 128)

然后第129行:

my @cols = $thumb->getscanline(y => $y);

给了我基本相同的错误。

此时我只想尝试将一个图像添加到数据库中。目录中有一个图像,我正在运行脚本来添加图像,名为“photo-216.jpg”。如果我将名称更改为“photo-1.jpg”或“photo-0.jpg”并将相应的“add_image”和“query_id”分别更改为1或0,则结果相同。

我确实有一个385 KB大的数据库来自运行下面的makedb.pl,但它填充了空字符。我重命名为“haar.db”。这是给我错误的数据库。如果我将haar.db文件重新创建为空文件,则脚本会挂起,几分钟后,它会给出不同的消息:

"This application has requested the Runtime to terminate it in an unusual way. Please contact the application's support team for more information."

如果没有“haar.db”,文件仍然会在这篇文章的标题中给出错误,而且与运行makedb.pl不同,我没有给出名为“haar.db”的数据库。

顺便说一下,当我尝试运行这个数据库填充脚本时,我得到了这个帖子标题错误的多个例子:http://www.drk7.jp/pub/imgseek/t/makedb.pl.txt/,我之前提到过。我在尝试之前显然删除了.txt扩展名。 makedb.pl脚本来自这个日语网站:http://www.drk7.jp/MT/archives/001258.html

如果我在2423扫描收藏邮票图像的目录中运行makedb.pl,我会得到362个错误实例。 2423邮票是删除我认为可能导致问题的“小”缩略图版本后的数字。

可能是,有些图像小于128像素,这是问题吗?但是,如果这是真的,为什么数据库会填充空字符?...除非它们不是真的为null,即使我正在使用的编辑器,Notebook ++,它们也是。

另请注意,我的图像是印章,有时只是完美的正方形。否则,有时候它们“风景”有时是“肖像”。也许问题是当“风景”缩放图像获得128像素的X轴然后它们的Y轴结束更少或更少。这可能吗?

非常感谢

1 个答案:

答案 0 :(得分:2)

更新:答案完全重组。

Image::Seek没有检查是否 scaleX返回错误。在您的情况下,对于某些图像,scaleX失败。 您似乎知道哪些图像scaleX失败了。所以,留下你的当前 代码放在一边,并编写一个简短的测试脚本:

#!/usr/bin/perl

use strict;
use warnings;

use Imager;

die "Specify image file name\n" unless @ARGV;

my ($imgfile) = @ARGV;

my $img = Imager->new;
$img->read( file => $imgfile )
    or die "Cannot read '$imgfile': ", $img->errstr;

my $x_scaled = $img->scaleX( pixels => 128 )
    or die 'scaleX failed: ', $img->errstr;

my $thumb = $x_scaled->scaleY( pixels => 128 )
    or die 'scaleY failed: ', $x_scaled->errstr;

__END__

运行此测试脚本,您收到错误消息:

Cannot read 'photo-1.jpg': format 'jpeg' not supported - formats bmp,
ico, pnm, raw, sgi, tga available for reading 

表示潜在问题:当您通过草莓安装Imager时 Perl的cpan,未安装pngjpg等的库。一 解决方案是使用提供的gcc编译器构建这些库 草莓Perl。

首先,您需要zlib

C:\Temp\zlib-1.2.3> copy win32\Makefile.gcc Makefile

prefix = /strawberry/c/local中设置Makefile。编译。你可能不得不这样做 手动将文件zlib.hzconf.h复制到 C:\strawberry\c\local\includezlib1.dlllibz.alibzdll.a C:\strawberry\c\local\lib(我不知道,因为我不经常使用Strawberry Perl而且我的草莓环境非常被忽视。)

然后,获取libpng。我使用了源存档,没有配置脚本。

C:\Temp\libpng-1.2.38> copy scripts\makefile.mingw Makefile
C:\Temp\libpng-1.2.38> make prefix=/strawberry/c/local ZLIBLIB=/strawberry/c/local/lib ZLIBINC=/strawberry/c/local/include

这构建了PNG库。同样,您可能需要手动复制.dll.a.h个文件到相应的目录。我这样做是因为我少了 比完美的草莓环境。

最后,获取JPEG library

C:\Temp\jpeg-7> copy Makefile.ansi Makefile

确保编辑此文件并设置CC=gcc。根据自定义jconfig.hjconfig.txt中的说明。我使用jconfig.dj作为基础。

您可能还想设置

CFLAGS= -O2
SYSDEPMEM= jmemansi.o
<{1>}中的

Makefile
#define DEFAULT_MAX_MEM 4*1024*1024 中的

。运行jconfig.h后,再次根据需要复制文件(并按照make的说明)。

安装库后,您可以

install.txt

产生:

C:\Temp> SET IM_INCPATH=C:\strawberry\c\local\include
C:\Temp> SET IM_LIBPATH=C:\strawberry\c\local\lib
C:\Temp> cpan
cpan> force install Imager

如果所有这些工作太多,那就是...... 叹息 我刚刚意识到 二进制文件位于GnuWin32