为什么我的图像在使用这个Perl CGI脚本时会被剪裁?
当我试图在Perl CGI脚本中将图像打印到STDOUT为什么我的图像在使用这个Perl CGI脚本时会被剪裁?,perl,cgi,jpeg,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(S
以下是代码:
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;
}
if($path=~m/\.jpe?g$/i)
{
我的$length=(stat($path))[7];
$| = 1;
打印“内容类型:图像/jpg\r\n”;
打印“内容长度:$length\r\n\r\n”;
打开(图像,编辑:由于统计数据
似乎没有问题,因此还有一些想法:
尝试使用无缓冲而不是缓冲读取,即使用而不是。或者反过来:同时使用缓冲read
和write
。此外,尝试注释。有关perl缓冲io的详细信息,请参阅。另请参阅此处,以获得一个明显有效的解决方案。编辑结束
您使用了错误的字段。(stat($path))[10]
是ctime:inode更改时间(以秒为单位,从纪元开始)。它应该是(stat($path))[7]
,大小:文件的总大小,以字节为单位。如果您确实想在提供服务之前将整个文件读取到内存中,请使用:
但是,对于大型图像,读取整个文件将消耗大量内存。因此,请参阅。FYI:我得出结论,这些图像实际上已损坏,尽管它们在Windows文件资源管理器中完全可见
FireFox浏览器显示剪辑的图像(无论它们是如何访问的,所以我想这不再是Perl的问题),但Safari浏览器完全显示它们
这些图像是在“jpg”模式下使用Java的imageIO重新采样的。我刚刚将模式更改为“png”,现在新生成的图像在所有浏览器中都能完美显示。因此,这实际上是Java imageIO的问题
问题解决了
谢谢大家的回复。您确定$length
包含正确的值吗?确保您希望看到的图像是正确的。文件本身是否已损坏?文件未损坏,因为我可以在windows中完全查看它们。是否包含内容长度无关紧要。我在您查看时更改了状态虽然被删除了,但图像还是被截掉了。我刚试过你的(更新)这里的代码:它正在工作。所以我猜这与您的图像有关。介意共享一个链接吗?这可能是服务器/安装问题吗?可能。但我认为这更可能与perl的缓冲io有关。请参阅上面的编辑。如果他使用图像的$length
调用read
,它不是在一次调用中读取的吗?我读取了c、 我确实认为有必要返回实际读取的字符数:在文件末尾读取时。例如:一个240字节的文件,具有$length
100:第一次读取返回100,第二次读取100,第三次/最后一次读取40。但是,当$length
是文件的大小时,read
应该读取整个文件或返回一个错误,但不是介于两者之间。不是吗?@ax你是对的。谢谢。清理我的帖子和评论。不过OP仍然需要检查read
和syswrite
的返回值。
#!/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' )
);