为什么我的图像在被这个Perl CGI脚本提供时会被剪裁?

时间:2010-02-05 12:01:21

标签: perl cgi jpeg

当我尝试在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;
}

3 个答案:

答案 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。或者相反:使用缓冲的readwrite。另外,请尝试评论$|。有关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问题。

它已经解决了。

感谢大家的回复。