当我尝试在Perl CGI脚本中将图像打印到STDOUT
时,在浏览器中查看时图像会被剪裁。
以下是代码:
if ($path =~ m/\.jpe?g$/i)
{
my $length = (stat($path))[7];
$| = 1;
print "Content-type: image/jpg\r\n";
print "Content-length: $length\r\n\r\n";
open(IMAGE,"<$path");
binmode(IMAGE);
binmode(STDOUT);
my ($image, $buff);
read IMAGE, $buff, $length;
syswrite STDOUT, $buff, $length;
close IMAGE;
}
答案 0 :(得分:5)
如果您确实想在投放前将整个文件读入内存,请使用File::Slurp:
#!/usr/bin/perl
use strict; use warnings;
use CGI::Simple;
use File::Slurp;
use File::stat;
local $| = 1;
my $cgi = CGI::Simple->new;
my $st = stat($path) or die "Cannot stat '$path'";
print $cgi->header(
-type => 'image/jpeg',
-length => $st->size,
);
write_file(\*STDOUT, {binmode => ':raw'},
\ read_file( $path, binmode => ':raw' )
);
但是,读取整个文件会占用大量图像的大量内存。因此,请参阅How can I serve an image with a Perl CGI script?。
答案 1 :(得分:2)
编辑:因为stat
似乎没有问题,还有更多想法:
尝试使用无缓冲而不是缓冲读取,即。使用sysread
代替read
。或者相反:使用缓冲的read
和write
。另外,请尝试评论$|
。有关perl buffered io的详细信息,请参阅Suffering from Buffering?。另请参阅此处的How can I serve an image with a Perl CGI script?以获得明显有效的解决方案。 编辑结束
您使用了错误的stat
字段。 (stat($path))[10]
是 ctime:自纪元以来的inode更改时间(以秒为单位)。它应该是(stat($path))[7]
, size:文件的总大小,以字节为单位。
答案 2 :(得分:0)
仅供参考:我得出的结论是,图像实际上已损坏,尽管它们在Windows文件资源管理器中完全可见。
FireFox浏览器显示剪辑的图像(无论它们如何被访问,所以我猜这不再是Perl问题),但Safari浏览器完全显示它们。
在“jpg”模式下使用Java的imageIO重新采样图像。我刚刚将模式更改为“png”,现在新生成的图像在所有浏览器中都显示出来。所以这实际上是一个Java imageIO问题。
它已经解决了。
感谢大家的回复。