Frage

Ich laufe zur Zeit in einigen Punkten von Bildern mit GD Größe ändern.

Alles funktioniert gut, bis ich ein animiertes GIF ändern möge, die das erste Bild auf einem schwarzen Hintergrund liefert.

Ich habe versucht, getimagesize verwenden, aber das gibt nur ich Dimensionen und nichts zwischen irgendeinem gif und einem animiert zu unterscheiden.

Die tatsächliche Größe neu bestimmen ist nicht für animierte Gifs erforderlich, nur sie in der Lage zu überspringen würde ausreichen, um für unsere Zwecke.

Irgendwelche Hinweise?

PS. Ich habe keinen Zugriff auf ImageMagick.

Mit freundlichen Grüßen

Kris

War es hilfreich?

Lösung

Es gibt einen kurzen Code-Snippet in der PHP-Seite der imagecreatefromgif() Funktion, die sein sollte, was Sie brauchen:

imagecreatefromgif Kommentar # 59787 von ZeBadger

Andere Tipps

Während für eine Lösung des gleichen Problems gesucht Ich habe bemerkt, dass die php.net Seite hat eine Follow-up, um den Code Davide und Kris beziehen sich auf, aber nach Ansicht des Autors, weniger speicherintensiv und möglicherweise weniger Plattenintensiv.

Ich werde es hier replizieren, weil es von Interesse sein kann.

Quelle: http://www.php.net/manual/ de / function.imagecreatefromgif.php # 88005

function is_ani($filename) {
    if(!($fh = @fopen($filename, 'rb')))
        return false;
    $count = 0;
    //an animated gif contains multiple "frames", with each frame having a
    //header made up of:
    // * a static 4-byte sequence (\x00\x21\xF9\x04)
    // * 4 variable bytes
    // * a static 2-byte sequence (\x00\x2C)

    // We read through the file til we reach the end of the file, or we've found
    // at least 2 frame headers
    while(!feof($fh) && $count < 2) {
        $chunk = fread($fh, 1024 * 100); //read 100kb at a time
        $count += preg_match_all('#\x00\x21\xF9\x04.{4}\x00[\x2C\x21]#s', $chunk, $matches);
    }

    fclose($fh);
    return $count > 1;
}

Hier ist die Arbeitsfunktion:

/**
 * Thanks to ZeBadger for original example, and Davide Gualano for pointing me to it
 * Original at http://it.php.net/manual/en/function.imagecreatefromgif.php#59787
 **/
function is_animated_gif( $filename )
{
    $raw = file_get_contents( $filename );

    $offset = 0;
    $frames = 0;
    while ($frames < 2)
    {
        $where1 = strpos($raw, "\x00\x21\xF9\x04", $offset);
        if ( $where1 === false )
        {
            break;
        }
        else
        {
            $offset = $where1 + 1;
            $where2 = strpos( $raw, "\x00\x2C", $offset );
            if ( $where2 === false )
            {
                break;
            }
            else
            {
                if ( $where1 + 8 == $where2 )
                {
                    $frames ++;
                }
                $offset = $where2 + 1;
            }
        }
    }

    return $frames > 1;
}

ganze Datei mit file_get_contents Lesen kann zu viel Speicherplatz verbrauchen, wenn die angegebene Datei zu groß ist. Ich habe wieder berücksichtigt die Funktion zuvor angegeben, die gerade genug Bytes liest Frames zu überprüfen und gibt, sobald es mindestens 2 Frames findet.

<?php
/**
 * Detects animated GIF from given file pointer resource or filename.
 *
 * @param resource|string $file File pointer resource or filename
 * @return bool
 */
function is_animated_gif($file)
{
    $fp = null;

    if (is_string($file)) {
        $fp = fopen($file, "rb");
    } else {
        $fp = $file;

        /* Make sure that we are at the beginning of the file */
        fseek($fp, 0);
    }

    if (fread($fp, 3) !== "GIF") {
        fclose($fp);

        return false;
    }

    $frames = 0;

    while (!feof($fp) && $frames < 2) {
        if (fread($fp, 1) === "\x00") {
            /* Some of the animated GIFs do not contain graphic control extension (starts with 21 f9) */
            if (fread($fp, 1) === "\x2c" || fread($fp, 2) === "\x21\xf9") {
                $frames++;
            }
        }
    }

    fclose($fp);

    return $frames > 1;
}

Dies ist eine Verbesserung des aktuellen Top-Antwort gestimmt, aber ich habe nicht genug Ruf noch zu kommentieren. Das Problem mit dieser Antwort ist, dass es die Datei in 100Kb Stücken liest und das Ende der Rahmenmarkierung könnte in zwischen zwei Stücken geteilt werden. Ein Update für das ist die letzte 20b des vorherigen Rahmens zum nächsten hinzuzufügen:

<?php
function is_ani($filename) {
  if(!($fh = @fopen($filename, 'rb')))
    return false;
  $count = 0;
  //an animated gif contains multiple "frames", with each frame having a
  //header made up of:
  // * a static 4-byte sequence (\x00\x21\xF9\x04)
  // * 4 variable bytes
  // * a static 2-byte sequence (\x00\x2C) (some variants may use \x00\x21 ?)

  // We read through the file til we reach the end of the file, or we've found
  // at least 2 frame headers
  $chunk = false;
  while(!feof($fh) && $count < 2) {
    //add the last 20 characters from the previous string, to make sure the searched pattern is not split.
    $chunk = ($chunk ? substr($chunk, -20) : "") . fread($fh, 1024 * 100); //read 100kb at a time
    $count += preg_match_all('#\x00\x21\xF9\x04.{4}\x00(\x2C|\x21)#s', $chunk, $matches);
  }

  fclose($fh);
  return $count > 1;
}

Animated GIF muss die folgende Zeichenfolge haben

"\x21\xFF\x0B\x4E\x45\x54\x53\x43\x41\x50\x45\x32\x2E\x30"

ich auf ein paar animierte Gifs getestet haben und es scheint die Saite am POS ist 781 einer Datei (gefunden mit file_get_contents und strpos)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top