为什么我的图像在使用此 Perl CGI 脚本提供服务时会被剪裁?

发布于 2024-08-20 01:07:17 字数 437 浏览 4 评论 0原文

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

When I try to print an image to STDOUT in a Perl CGI script, the image gets clipped when viewed in the browser.

Here is the following code:

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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

一抹淡然 2024-08-27 01:07:17

如果您确实想在服务之前将整个文件读入内存,请使用 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' )
);

但是,对于大图像,读取整个文件会消耗大量内存。因此,请参阅我该如何使用 Perl CGI 脚本提供图像?

If you really want to read the entire file into memory before serving, use 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' )
);

However, reading the entire file will consume large amounts of memory for large images. Therefore, see How can I serve an image with a Perl CGI script?.

萌能量女王 2024-08-27 01:07:17

编辑:由于stat似乎没有问题,还有一些想法:

尝试使用无缓冲而不是缓冲读取,即。使用 sysread 而不是 读取。或者反之亦然:同时使用缓冲的readwrite。另外,尝试注释掉 $| 。有关 perl 缓冲 io 的详细信息,请参阅 正在遭受缓冲? 。另请参阅如何我可以使用 Perl CGI 脚本提供图像吗? 这里有一个明显有效的解决方案。 编辑结束

您使用了错误的stat 字段。 (stat($path))[10]ctime:自纪元以来 inode 更改时间(以秒为单位)。它应该是(stat($path))[7]size:文件总大小,以字节为单位

EDIT: as the stat doesn't seem to be problem, some more ideas:

try using unbuffered instead of buffered reading, ie. use sysread instead of read. or the other way round: use both buffered read and write. also, try commenting out the $|. see Suffering from Buffering? for details on perl buffered io. see also How can I serve an image with a Perl CGI script? here on SO for an apparently working solution. EDIT END

you are using the wrong stat field. (stat($path))[10] is ctime: inode change time in seconds since the epoch. it should be (stat($path))[7], size: total size of file, in bytes.

海拔太高太耀眼 2024-08-27 01:07:17

仅供参考:我得出的结论是,这些图像实际上已损坏,尽管它们在 Windows 文件资源管理器中完全可见。

FireFox 浏览器显示图像被剪切(无论如何访问它们,所以我想这不再是 Perl 问题),但 Safari 浏览器完全显示它们。

图像是使用 Java 的 imageIO 以“jpg”模式重新采样的。我刚刚将模式更改为“png”,现在新生成的图像在所有浏览器中都能完美显示。所以这实际上是一个 Java imageIO 问题。

解决了。

谢谢大家的回复。

FYI: I have come to the conclusion that the images are in fact corrupt, though they are fully viewable in Windows File Explorer.

The FireFox browser shows the Images clipped(no matter how they are accessed, so I guess this is no longer a Perl problem), but the Safari Browser displays them completely.

The images were re sampled from using Java's imageIO in "jpg" mode. I just changed the mode to "png", and now the newly generated images are showing perfectly in all browsers. So this was actually a Java imageIO issue.

It is solved.

Thank you everyone for your responses.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文