Kathrin: Datei-Upload Filehandle Problem

Hallo!

Ich will ein Bild auf meinen Server uploaden und es anschließend mit ImageMagick verkleinern.

Wenn das Bild bereits auf dem Server gespeichert ist, funktioniert alles wunderbar. Aber wenn ich es hochlade, kann ich es nicht öffnen und auch nicht einlesen, egal wie ich es versuche.

Ich denke, ich benutze den filehandle nicht richtig.

#Hochgeladenes Bild auffangen
$file = ($cgi->upload('B'));

#So hab ich's zuerst probiert, ging aber nicht, weil:
results: Exception 435: unable to open image `REF(0x83329e4)': No such file or directory

my $results = $Image->Read($file);# or die "Fehler beim Lesen!";

print "<br>results: ",$results;

Wenn ich am Anfang das Bild ohne den Schrägstrich auffange:

$file = $cgi->upload('B');

bekomme ich die diese Fehlermeldungen:
results: Exception 410: Must specify image size `\Video\rose.jpg'

#Und so geht's leider auch nicht

open(DATEI, "<$file");
my $results = $Image->Read(*DATEI);
print "<br>results: ",$results;
close(DATEI);

weil:
results: Exception 435: unable to open image `*main::DATEI': No such file or directory

Hier ändert sich die Fehlermeldung übrigens nicht, egal wie ich das Bild am Anfang auffange.

Ich hoffe ihr könnt mir helfen, mir fallen nämlich langsam keine Möglichkeiten mehr ein, was zu verändern.
Danke
Kathrin

  1. #Hochgeladenes Bild auffangen
    $file = ($cgi->upload('B'));

    Hier weist Du $file eine Referenz auf den Filehandle der hochgeladenen Datei zu, was Dir auch diese Fehlermeldung:

    results: Exception 435: unable to open image `REF(0x83329e4)'

    sagen will.

    Wenn ich am Anfang das Bild ohne den Schrägstrich auffange:

    $file = $cgi->upload('B');

    bekomme ich die diese Fehlermeldungen:
    results: Exception 410: Must specify image size `\Video\rose.jpg'

    Das sagt Dir wiederum, dass das Filehandle korrekt übergeben wird, der aufgerufenen Funktion allerdings ein Argument fehlt, nämlich die Größe der Grafik. Da Du vermutlich Image::Magick benutzt, solltest Du Dir mal die Doku anschauen und zudem ein bisschen mehr Code preisgeben.

    Siechfred

    --
    Hinter den Kulissen passiert viel mehr, als man denkt, aber meistens nicht das, was man denkt.
    1. Nachtrag:

      So sollte es funktionieren:

      use CGI;  
      use Image::Magick;  
        
      my $cgi = CGI->new;  
      my $fh = $cgi->upload('name');  
        
      my $img = Image::Magick->new;  
      my $res = $img->Read( file => \*$fh );
      

      (siehe Magick-Bugs Mailingliste)

      Siechfred

      --
      Hinter den Kulissen passiert viel mehr, als man denkt, aber meistens nicht das, was man denkt.
      1. Bei mir sieht's im Moment so aus:

        #!/usr/bin/perl -w
        print "Content-type: text/html\n\n";

        use strict;
        use CGI;
        use CGI::Carp qw(fatalsToBrowser);
        #use DBI;
        use Image::Magick;
        my $Image = Image::Magick->new;
        #$CGI::POST_MAX=1024 * 100 || die "Datei zu groß";

        my $cgi = new CGI;
        my ($file);

        if($cgi->param()){

        if($cgi->upload('B')){

        #my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
        #$atime,$mtime,$ctime,$blksize,$blocks)
        #= stat($cgi->upload('B'));

        $file = $cgi->upload('B');
        print "<br>file: ",$file;

        }

        open(DATEI, "<$file");# || die "Datei nicht gefunden";
         my @Zeilen = <DATEI>;
         close(DATEI);

        print "<br>Zeilen: ",@Zeilen;

        my $results = $Image->Read($file);# or die "Fehler beim Lesen!";
            print "<br>results: ",$results;

        open(DATEI, "<$file");
            my $results = $Image->Read(*DATEI);
            print "<br>results: ",$results;
            close(DATEI);

        $Image->Thumbnail('500x500>');
            $Image->Write("test.jpg");

        undef $Image;
            undef $file;

        }

        1. Bei mir sieht's im Moment so aus:
              my $results = $Image->Read($file);# or die "Fehler beim Lesen!";

          Ändere diese Zeile bitte mal, so wie von mir vorgeschlagen.

          Siechfred

          --
          Hinter den Kulissen passiert viel mehr, als man denkt, aber meistens nicht das, was man denkt.
          1. Also so geht's immernoch nicht:

            my $results = $Image->Read(\*$file);# or die "Fehler beim Lesen!";
                print "<br>results: ",$results;

            Aber so macht's zumindest schonmal keine Fehler mehr:

            my $results = $Image->Read( file => \*$file );# or die "Fehler beim Lesen!";
            print "<br>results: ",$results;

            Ich probier gleich mal aus, ob das Bild auch weiterverarbeitet wird...

            Aber Danke schonmal

            1. Wow! Perfekt Danke!
              Alles funktioniert genauso wie ich's wollte!

              Da wär ich aber echt nie draufgekommen "file =>" noch mit hinzuschreiben.
              Ich dachte das wäre keine Pflichtangabe, schließlich kann man bei resize ja dann auch width und height weglassen.

              Auf jedenfall 1000 Dank!!!

              P.S.:
              ... Du kennst Dich nicht zufällig mit fork auch aus? :-)

              Ich weiß nämlich nicht genau, ob ich bei solchen Scripten fork benutzen muß, oder nicht.
              Alle meine Scripte benutzen höchstens mal sendmail, oder machen eine MySQL-Anfrage.

              1. Alles funktioniert genauso wie ich's wollte!

                Schön, freut mich für Dich :)

                ... Du kennst Dich nicht zufällig mit fork auch aus? :-)

                Ein bisschen...

                Ich weiß nämlich nicht genau, ob ich bei solchen Scripten fork benutzen muß, oder nicht.

                Naja, zwingend nötig ist es m.E. nicht, für die Bildverarbeitung einen extra Prozess zu starten, selbst wenn es länger dauert. Sinnvoll ist sowas eigentlich nur, wenn Dein Programm mehrere Dinge gleichzeitig tun soll. Wenn es Dich trotzdem interessiert, schau Dir mal diesen Artikel an.

                Siechfred

                --
                Hinter den Kulissen passiert viel mehr, als man denkt, aber meistens nicht das, was man denkt.
                1. Da steht:

                  Wir sollen 100 mal das gleiche machen – aber bitte gleichzeitig! Ein Beispiel, wo so etwas vorkommen könnte ist ein Server, der 100 Verbindungen gleichzeitig eingehen kann.

                  Bedeutet das, wenn 100 Leute gleichzeitig diese Forumsseite aktualisieren und der Server dann 100 Datenbank-Anfragen gleichzeitig macht, braucht man fork?
                  Ich nehme an MySQL ist das egal, aber was ist mit dem Script das die Anfrage macht?

                  1. Bedeutet das, wenn 100 Leute gleichzeitig diese Forumsseite aktualisieren und der Server dann 100 Datenbank-Anfragen gleichzeitig macht, braucht man fork?

                    Nicht zwingend, es sei denn, das Perl-Script selber fungiert als Serversoftware. Ansonsten wird bei jeder Anfrage an den Server das Script neu gestartet und verrichtet seinen Dienst unabhängig von den anderen Prozessen. In Deinem Fall würde das Forenscript also 100 mal parallel laufen. Wäre das Perl-Script die eigentliche Serversoftware (quasi ein Perl-Apache), dann hättest Du Recht und es müsste bei jeder eingehenden Anfrage ein neuer Kindprozess gestartet werden.

                    Daneben gibt es in Perl das Konzept der Threads, wenn Dich das für den Moment nicht überfordert, schau Dir mal perlthrtut an. Allerdings kann ich dazu nicht viel beisteuern, da ich mich damit noch nicht gründlicher beschäftigt habe.

                    Siechfred

                    --
                    Hinter den Kulissen passiert viel mehr, als man denkt, aber meistens nicht das, was man denkt.
                    1. Ich verstehe das jetzt so:

                      Wenn ich ein Script db.pl habe, in dem ich mit DBI eine Datenbankverbindung aufbaue, wird das einfach bei 100 gleichzeitigen Anfragen 100 Mal nebeneinander geöffnet.

                      Und das gilt für alle Perl-Scripte auf dem Server und für die HTML-Seiten sowieso.

                      Dann muß ich mir ja gar keine Sorgen machen.
                      Ich dachte schon, wenn 100 Leute gleichzeitig was aufrufen, ist der 1. glücklich und alle anderen bekommen einen Fehler zu sehen. :-)

                      1. Wenn ich ein Script db.pl habe, in dem ich mit DBI eine Datenbankverbindung aufbaue, wird das einfach bei 100 gleichzeitigen Anfragen 100 Mal nebeneinander geöffnet.

                        Genau.

                        Dann muß ich mir ja gar keine Sorgen machen.

                        Nun ja, Du kannst einen Server schon in die Knie zwingen (Stichwort Denial of Service), aber im Regelfall brauchst Du Dir in dieser Hinsicht wirklich keine Gedanken zu machen. Wenn Du gerade bei CGI-Anwendungen in Verbindung mit Datenbanken die Performance optimieren möchtest, könnte sich übrigens ein Blick auf mod_perl empfehlen.

                        Ich dachte schon, wenn 100 Leute gleichzeitig was aufrufen, ist der 1. glücklich und alle anderen bekommen einen Fehler zu sehen. :-)

                        Du hast halt Glück, dass Dir mit MySQL ein fähiger Partner zur Verfügung steht, der Dir in dieser Hinsicht einiges an Sicherheitsmaßnahmen abnimmt. Aber grundsätzlich solltest Du Dir mal den Artikel Sperren von Dateien zu Gemüte führen, da werden oft Fehler gemacht.

                        Siechfred

                        --
                        Hinter den Kulissen passiert viel mehr, als man denkt, aber meistens nicht das, was man denkt.