kostenloser Webspace werbefrei: lima-city


Auflösung bei PHP Images

lima-cityForumProgrammiersprachenPHP, MySQL & .htaccess

  1. Autor dieses Themas

    o**s

    Wie kann man die Auflösung der mit PHP erzeugten Grafiken einstellen? Ich habe es schon versucht, ein ganz großes Bild zu generieren und es anschließend mit imagecopyresampled() auf die notwendige Größe zu verkleinern. Das einzige was sich dabei ändert ist die Dateigröße (auch noch bei gleichbleibender Auflösung von recht wenigen 96dpi).
    Google bietet keine plausiblen Erklärungen, php.net auch nicht.
    Danke für die Hilfe im Voraus.
  2. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

  3. ich habe mal ein wenig bei gallery2 im Quelltext gestöbert - dort gibt es eine ähnliche Funktion:

    function _imageCopyResampled($dstRes, $srcRes, $dstX, $dstY, $srcX, $srcY,
                                     $dstW, $dstH, $srcW, $srcH) {
            $gd =& $this->_getGdFunctionality();
            if ($gd->functionExists(\'imageCopyResampled\')) {
                $ret = $gd->imageCopyResampled($dstRes, $srcRes, $dstX, $dstY, $srcX, $srcY,
                                               $dstW, $dstH, $srcW, $srcH);
            } else {
                /* Fallback */
                $ret = $gd->imageCopyResized($dstRes, $srcRes, $dstX, $dstY, $srcX, $srcY,
                                             $dstW, $dstH, $srcW, $srcH);
            }
            if ($ret) {
                return $ret;
            }
            return null;


    vielleicht kannst Du ja etwas damit anfangen...
  4. Autor dieses Themas

    o**s

    function _imageCopyResampled($dstRes, $srcRes, $dstX, $dstY, $srcX, $srcY,
                                     $dstW, $dstH, $srcW, $srcH) {
            $gd =& $this->_getGdFunctionality();
            if ($gd->functionExists(\'imageCopyResampled\')) {
                $ret = $gd->imageCopyResampled($dstRes, $srcRes, $dstX, $dstY, $srcX, $srcY,
                                               $dstW, $dstH, $srcW, $srcH);
            } else {
                /* Fallback */
                $ret = $gd->imageCopyResized($dstRes, $srcRes, $dstX, $dstY, $srcX, $srcY,
                                             $dstW, $dstH, $srcW, $srcH);
            }
            if ($ret) {
                return $ret;
            }
            return null;


    Das ist doch aber nur die Anwendung eben derselben Funktion, die ich auch verwende. Es soll nur sicherstellen, dass im Zweifelsfall die imageCopyResized() genommen wird. Aber das bringt mir alles überhaupt nichts. Soviel ich weiß wird bei der letzten Funktion die Dateigröße beibehalten, dadurch unterscheidet sie sich von der ersten.
    Ich brauche eine Änderung der Auflösung, nicht der Größe.

  5. Ich brauche eine Änderung der Auflösung, nicht der Größe.


    Upps...hatte ich falsch verstanden....
  6. Autor dieses Themas

    o**s

    Post 1: Ändert sich die Auflösung denn, wenn man ein anderes Dateiformat nimmt?

    Post 2: Gibt es da wirklich keine Möglichkeit mit PHP?

    //Anmerkung: Doppelposts bitte vermeiden!

    Beitrag geändert: 5.8.2008 10:14:09 von sebigisler
  7. m******s

    Ich habe nichts so ganz verstanden, was du überhaupt willst und was das Problem mit imagecopyresampled() bzw. imagecopyresized() ist...
    Also, wenn ich dich richtig verstanden habe, willst du die absolute Auflösung deiner Bilder ändern, das sollte mit einer der beiden Funktionen gehen.
    Oder du willst die relative Auflösung ändern, aber die hängt vor allem vom jeweiligen Anzeigerät (Monitor/Drucker/...) ab und auch wenn es theoretisch bei einigen Grafikformaten die Möglichkeit gibt, die einzustellen, ist das sehr unüblich, soweit ich weiß, und es wundert mich deshalb gar nicht, dass das bei PHP nicht geht...
    Also, was m.E. nach helfen würde zur Problemlösung wäre dein Code, eine genaue Beschreibung, was das erwartete Ergebnis ist, und was das tatsächliche Ergebnis ist, und wo der Unterschied ist... Ich für meinen Teil habe nicht ganz perfekt dein Problem erkannt...

  8. Wie kann man die Auflösung der mit PHP erzeugten Grafiken einstellen? Ich habe es schon versucht, ein ganz großes Bild zu generieren und es anschließend mit imagecopyresampled() auf die notwendige Größe zu verkleinern. Das einzige was sich dabei ändert ist die Dateigröße (auch noch bei gleichbleibender Auflösung von recht wenigen 96dpi).
    Google bietet keine plausiblen Erklärungen, php.net auch nicht.
    Danke für die Hilfe im Voraus.


    Falls du die dpi-Angaben meinst, die diverse Grafik-Datei-Formate mit sich rumtragen, die kannst du mit PHP\'s Image-Funktionen derzeit nicht ändern. Dafür musst du direkt in der Datei-Struktur rumfummeln. Sowohl JFIF (das meistverwendete JPEG-Datei-Format im Internet), als auch EXIF und PNG haben dafür Segmente/Chunks/Tags in ihren Datenstrukturen reserviert.

    Diese zu ändern oder einzufügen geht in PHP nur mit fopen(), fread(), fwrite() und Verwandten. Außerdem musst du natürlich jedes Dateiformat kennen. Zumindest für EXIF gibts auch irgendwo im PHP-Handbuch in der Abteilung http://de.php.net/manual/de/ref.image.php einen Link auf eine Funktionsbibliothek, die diese Daten bearbeiten kann.
  9. Autor dieses Themas

    o**s

    merovius schrieb:
    Ich habe nichts so ganz verstanden, was du überhaupt willst und was das Problem mit imagecopyresampled() bzw. imagecopyresized() ist...
    Also, wenn ich dich richtig verstanden habe, willst du die absolute Auflösung deiner Bilder ändern, das sollte mit einer der beiden Funktionen gehen.
    Oder du willst die relative Auflösung ändern, aber die hängt vor allem vom jeweiligen Anzeigerät (Monitor/Drucker/...) ab und auch wenn es theoretisch bei einigen Grafikformaten die Möglichkeit gibt, die einzustellen, ist das sehr unüblich, soweit ich weiß, und es wundert mich deshalb gar nicht, dass das bei PHP nicht geht...
    Also, was m.E. nach helfen würde zur Problemlösung wäre dein Code, eine genaue Beschreibung, was das erwartete Ergebnis ist, und was das tatsächliche Ergebnis ist, und wo der Unterschied ist... Ich für meinen Teil habe nicht ganz perfekt dein Problem erkannt...


    Ich meine die dpi-Zahl. Was ist denn für ein Unterschied zwischen absoluter und relativer Auflösung und wie kann man die absolute Auflösung mit PHP bitte ändern?

    alopex schrieb:
    Falls du die dpi-Angaben meinst, die diverse Grafik-Datei-Formate mit sich rumtragen, die kannst du mit PHP\\\'s Image-Funktionen derzeit nicht ändern. Dafür musst du direkt in der Datei-Struktur rumfummeln. Sowohl JFIF (das meistverwendete JPEG-Datei-Format im Internet), als auch EXIF und PNG haben dafür Segmente/Chunks/Tags in ihren Datenstrukturen reserviert.

    Diese zu ändern oder einzufügen geht in PHP nur mit fopen(), fread(), fwrite() und Verwandten. Außerdem musst du natürlich jedes Dateiformat kennen. Zumindest für EXIF gibts auch irgendwo im PHP-Handbuch in der Abteilung http://de.php.net/manual/de/ref.image.php einen Link auf eine Funktionsbibliothek, die diese Daten bearbeiten kann.


    Ist EXIF auf lima-city ein erlaubtes Format? Und kann PHP solche Images mit den Standardfunktionen erzeugen?
  10. m******s

    Ich meine die dpi-Zahl.


    Also die relative Auflösung.

    Was ist denn für ein Unterschied zwischen absoluter und relativer Auflösung


    Absolute Auflösung ist z.B. 1024*768 px. D.h. es wird angegeben, wie viele Pixel für das Bild tatsächlich gespeichert sind. Die relative Auflösung sagt aus, wieviele Pixel einen cm (oder Zoll oder was auch immer) ausmachen. Aus dieser lässt sich also ererchnen, wie groß das Bild ist, wenn es auf dem Monitor angezeigt wird, oder beim Drucker ausgedruckt wird. Diese Größe hängt aber m.E. nach auch sehr kritisch vom Anzeigegerät ab. Wenn man z.B. einen 22-Zoll und einen 19-Zoll-Monitor mit gleicher Auflösung (also absolute auflösung in dem Fall) laufen lässt, würde das Bild auf dem 22-Zoller größer angezeigt werden, weil bei ihm \"die Pixel größer sind\".
    Man kann zwar auch eine relative Auflösung speichern, das ist aber nur begrenzt sinnvoll und recht unüblich, soweit ich weiß.
    Was willst du denn erreichen? Wenn du das Bild z.B. als thumbnail anzeigen lassen willst, würde es reichen, es mit imagecopyresized() runterzuskalieren. Deswegen sagte ich ja, ein Stück Quellcode mit einer ausführlichen Beschreibung, was das von dir gewollte Ergebnis ist, und was das erreichte Ergebnis ist, wäre sehr hilfreich.

    und wie kann man die absolute Auflösung mit PHP bitte ändern?


    Hier mal als Beispiel - aus dem PHP-Handbuch - eine Funktion, die das Bild auf die halbe Größe skaliert (halbe absolute Auflösung):

    <?php
    // The file
    $filename = \'test.jpg\';
    $percent = 0.5; //Hier liesse sich jeder beliebige Faktor eintragen
    
    // Content type
    header(\'Content-type: image/jpeg\');
    
    // Get new dimensions
    list($width, $height) = getimagesize($filename);
    $new_width = $width * $percent;
    $new_height = $height * $percent;
    
    // Resample
    $image_p = imagecreatetruecolor($new_width, $new_height);
    $image = imagecreatefromjpeg($filename);
    imagecopyresampled($image_p, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
    
    // Output
    imagejpeg($image_p, null, 100);
    ?>


    Das Ergebnis ist das Bild, zwar mit der selben relativen Auflösung (\"dpi-Zahl\"), aber um den Faktor 1/2 skaliert.
    Das ist aber anscheinend ja nicht, was du willst, aber das was du willst ist m.E. nach mit PHP nicht möglich (oder nur wie von alopex beschrieben per fopen, fwrite, etc...) und auch nicht sinnvoll. Aber wie gesagt, am besten kann man dir wohl helfen, wenn du mal mithilfe von Source etc. klarmachst, wieso du diesen Kram ändern willst.

    PS: Dieser Post bringt mich auf genau 5000 Gulden :lol:

  11. Ist EXIF auf lima-city ein erlaubtes Format? Und kann PHP solche Images mit den Standardfunktionen erzeugen?


    1. Klar. Es ist eine Unterart des Formates \"JIF\" (JPEG Image (File) Format). Dieses allgemeine Format umfasst alles, was im Volksmund als JPEG/JPG-Grafik-Dateien bezeichnet wird. EXIF enthält nur einige zusätzliche Informationen innherhalb der Datei.

    2. Die PHP-Image-Funktion imagejpeg() erzeugt JFIF-Dateien.

    Eventuell kannst du auch IrfanView im Batch-Konvertierungsmodus auf eine ganze Gruppe von Bildern anwenden. Die Änderung der Auflösung befindet sich hier in einem etwas unübersichtlichen Fenster, dass sich öffnet, wenn man den Button \"Spezial-Optionen\" anklickt.

    Ich hab mal auf die Schnelle was zusammengezimmert, was die DPI-Einstellungen bei mit imagejpeg() erstellten Dateien ändert.

    <?php
    /*
    @version history:
    2008-08-06; 0.0; NFO: created;
                     NFO: seems to work;
    */
    /**
    = Class jfif_aspect_ratio
    (c)2008 EisFuX/eXecbase
    == Synopsis
    Allows reading and editing of aspect ratio settings in JFIF compatible files.
    Only the settings in the JFIF-APP0-segment are changed, but picture data stays unchanged.
    == Compatibility Notes
    This class should also work with PHP 4, if you rename the constructor method.
    */
    
    /// allows extracting and editing of aspect ratio settings in JFIF files (gdlib generated)
    class jfif_aspect_ratio {
      ///
      function __construct() {
        $this->_dpi_offset = 13;
        $this->_fh = FALSE;
      }
      
      ///
      function __destruct() {
        $this->close();
      }
      
      /// opens a file and checks if it\'s a valid JFIF; returns TRUE on success, FALSE otherwise
      function open(
        $file = NULL /// PATH to an existing file
      ) {
        if (is_resource($this->_fh)) {
          // try to close an already opened filehandle
          if (!$this->close()) {
            return FALSE;
          }
        }
        // try to open file
        if (!$this->_fh = fopen($file, \'r+\')) {
          if (!file_exists($file)) {
            $error = sprintf(\'file \"%s\" does not exist\', (string) $file);
          }
          else {
            $error = sprintf(\'could not open file \"s%\" for unknown reason\', (string) $file);
          }
          trigger_error($this->error($error));
          return FALSE;
        }
        
        if (!flock($this->_fh, LOCK_EX | LOCK_NB)) {
          trigger_error($this->error(\'locking failed\'));
          return FALSE;
        }
    
    
        if (11 > strlen($magic_bytes = fread($this->_fh, 11))) {
          trigger_error($this->error(\'could not read magic bytes\'));
          $this->close();
          return FALSE;
        }
        // is it a valid JFIF file generated by PHP\'s gdlib?
        // magic bytes: \'ÿØÿà--JFIF\': \'--\' holds the segment size
        if (!preg_match(\'/\\AÿØÿà..JFIF\\x00/s\', $magic_bytes)) {
          trigger_error($this->error(\'given file is not a gdlib generated JFIF\'));
          $this->close();
          return FALSE;
        }
        return TRUE;
      }
      
      /// closes the file
      function close() {
        if (!is_resource($this->_fh)) {
          return FALSE;
        }
        flock($this->_fh, LOCK_UN); // unlock
        $success = fclose($this->_fh);
        $this->_fh = FALSE;
        return (bool) $success;
      }
      
      /// gets aspect ratio data from file as HASH; returns FALSE on failure
      function read() {
        if (!is_resource($this->_fh)) {
          return FALSE;
        }
        
        fseek($this->_fh, $this->_dpi_offset);
        if (5 > strlen($bytes = fread($this->_fh, 5))) { // 5 == sizeof struct \'Cunit/nx/ny\'
          trigger_error($this->error(\'could not read from file\'));
          return FALSE;
        }
    
        $info = unpack(\'Cunit/nx/ny\', $bytes);
        if (!is_array($info)) {
          trigger_error($this->error(\'unpacking failed\'));
          return FALSE;
        }
        
        return $info;
      }
      
      /// sets resolution info in file; returns TRUE on success, FALSE otherwise
      function write(
        $info = NULL /// HASH(\'unit\' => 0...2, \'x\' => 0...65535, \'y\' =>  0...65535)
      ) {
        if (!is_resource($this->_fh)) {
          return FALSE;
        }
        
        $info[\'x\'] = (int) $info[\'x\'];
        if ($info[\'x\'] < 0 || $info[\'x\'] > 0xffff) {
          trigger_error($this->error(\'invalid value %s for x dimension\', $info[\'x\']));
          return FALSE;
        }
        $info[\'y\'] = (int) $info[\'y\'];
        if ($info[\'y\'] < 0 || $info[\'y\'] > 0xffff) {
          trigger_error($this->error(\'invalid value %s for y dimension\', $info[\'y\']));
          return FALSE;
        }
        // 0: pixel aspect ratio
        // 1: dots per inch
        // 2: dots per cm
        $info[\'unit\'] = (int) $info[\'unit\'];
        if ($info[\'unit\'] < 0 || $info[\'unit\'] > 2 ) {
          $info[\'unit\'] = 0;
        }
        fseek($this->_fh, $this->_dpi_offset);
        if (!fwrite($this->_fh, pack(\'Cnn\', $info[\'unit\'], $info[\'x\'], $info[\'y\']))) {
          trigger_error($this->error(\'could not write to file\'));
          return FALSE;
        }
        return TRUE;
      }
      
      /// provides error string for output using trigger_error()
      function error() {
        if (!func_num_args()) {
          $msg = \'\';
        }
        else {
          $args = func_get_args();
          $msg = (1 === func_num_args()) ? $args[0] : vsprintf(array_shift($args), $args);
        }
    
        list(, $dbbt, ) = debug_backtrace();
        return sprintf(\'%s. Error occured during calling %s%s%s() in file <b>%s</b> on line <b>%s</b>, defined\', $msg, $dbbt[\'class\'], $dbbt[\'type\'], $dbbt[\'function\'],  $dbbt[\'file\'], $dbbt[\'line\']);
      }
    
    }
    
    /**
    = $info HASH
    
    $info = array (
     \'unit\' => 0: pixels 1: dots-per-inch 2: dots-per-cm
     \'x\' => horicontal resolution (0...65535)
     \'y\' => vertical resolution (0...65535)
    );
    */
    
    /// example of using
    $infile = \'f:/jif_test/jfif_dpi_edit.jpg\';
    
    $jr = new jfif_aspect_ratio;
    
    $is_open = $jr->open($infile);
    $info = $jr->read();
    $is_written = $jr->write(array (\'unit\' => 0, \'x\' => 96, \'y\' => 96));
    ?>



    Beitrag geändert: 6.8.2008 21:26:25 von alopex
  12. Autor dieses Themas

    o**s

    Ich habe eine Anwendung, welche Sinuskurven ausgibt; jeder Pixel wird per Formel berechnet. Damit die Zeichnungen schärfer sind, möchte ich die relative Auflösung vergrößern. D.h. ich erzeuge ein großes Bild und verkleinere es dann so, dass "die Pixel enger zusammenrücken".

    @alopex
    Danke für das Script. Ich habe nur eine Fehlermeldung, dass die Datei kein JFIF-File ist. Hier meine Funktion:
    <?php
    function drawDiagramm ($type="jpeg")
    {
      header('Content-type: image/'.$type);
      header("Cache-Control: no-cache, must-revalidate");           
      header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
      imagecopyresampled($this->diagramm, $this->diagramm, 0, 0, 0, 0, $this->breit, $this->hoch, $this->width, (1+$this->margin)*$this->height);
      $jr = new jfif_aspect_ratio();
      $infile = "jpf".rand(1000,9999).".jpg";
      switch ($type)
      {
        case "gif":
          imagegif($this->diagramm);
        break 1;
    
        case "jpeg":
          imagejpeg($this->diagramm,$infile);
        break 1;
    
        case "jpg":
          imagejpeg($this->diagramm,$infile);
        break 1;
    
        default:
          imagepng($this->diagramm);
        break 1;
      }
      $is_open = $jr->open($infile);
      $info = $jr->read();
      $is_written = $jr->write(array ('unit' => 0, 'x' => 96, 'y' => 96));
      $file = file($infile);
      foreach ($file as $row)
      {
        echo $row;
      }
    }
    ?>

    Der Fehler erscheint in Zeile 28.

    Mir fällt nur gerade auf, dass das ganze auf diese Weise nicht funktionieren wird, so wie ich es möchte. Denn die Pixel würden nach Erhöhen der Auflösung nicht genauer gesetzt. D.h. ich muss ein großes Bild zeichnen, es speichern, die Auflösung und dann noch Größe verändern, damit die "Pixel dichter zusammenrücken"...
    Aber wer weiß, in diesem Forum bekommt man doch für fast alles eine Lösung.
  13. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

Dir gefällt dieses Thema?

Über lima-city

Login zum Webhosting ohne Werbung!