Почему мои изображения обрезаются при работе с этим сценарием Perl CGI? - PullRequest
2 голосов
/ 05 февраля 2010

Когда я пытаюсь напечатать изображение на STDOUT в сценарии Perl CGI, изображение обрезается при просмотре в браузере.

Вот следующий код:

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 ]

5 голосов
/ 05 февраля 2010

Если вы действительно хотите прочитать весь файл в память перед обслуживанием, используйте 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-скрипта? .

2 голосов
/ 05 февраля 2010

РЕДАКТИРОВАТЬ : поскольку stat не кажется проблемой, есть еще несколько идей:

попробуйте использовать небуферизованное вместо буферизованного чтения, т.е. используйте sysread вместо read. или наоборот: используйте оба буфера read и write. также попробуйте закомментировать $|. см. Страдает от буферизации? для получения подробной информации о буфере Perl io. см. также Как я могу предоставить изображение с помощью сценария Perl CGI? здесь, на SO для явно работающего решения. РЕДАКТИРОВАТЬ КОНЕЦ

вы используете неправильное поле stat. (stat($path))[10] равно ctime: время смены inode в секундах с начала эпохи . должно быть (stat($path))[7], размер: общий размер файла, в байтах .

0 голосов
/ 08 февраля 2010

К вашему сведению: я пришел к выводу, что изображения на самом деле повреждены, хотя они полностью доступны для просмотра в проводнике Windows.

Браузер FireFox показывает обрезанные изображения (независимо от того, как к ним осуществляется доступ, поэтому, я думаю, это больше не проблема Perl), но браузер Safari отображает их полностью.

Изображения были повторно взяты с использованием Java imageIO в режиме "jpg". Я просто изменил режим на «png», и теперь вновь созданные изображения отлично отображаются во всех браузерах. Так что на самом деле это проблема Java imageIO.

Решено.

Спасибо всем за ваши ответы.

...