/** * Extract gif frames, not the animation, just the frame components. Animation details are retained though. * * @param string $srcFile * @param string $dstDir * @param string $dstFilePrefix * * @throws Exception */ public static function extract($srcFile, $dstDir, $dstFilePrefix = null) { $fh = new FileHandler(); try { $fh->openFile($srcFile); } catch (Exception $e) { throw $e; } $header = new Header($fh); if ($header->signature !== "GIF" && $header->version !== "87a" && $header->version !== "89a") { $fh->closeFile(); throw new Exception("Not a gif file."); } $dstDir = str_replace("\\", "/", $dstDir); if ($dstFilePrefix == null) { $dstFilePrefix = basename($srcFile, '.gif'); } $lc = substr($dstDir, -1); if ("/" !== $lc) { $dstDir .= "/"; } $dstPath = $dstDir . $dstFilePrefix . "_"; $lsd = new LogicalScreenDescriptor($fh); self::processGifStream($fh, $lsd, $dstPath); $fh->closeFile(); }
/** * @param string $file * * @return array with "width" and "height" of the gif file. * @throws Exception */ public static function getSize($file) { $fh = new FileHandler(); try { $fh->openFile($file); } catch (Exception $e) { throw $e; } $header = new Header($fh); if ($header->signature !== "GIF" && $header->version !== "87a" && $header->version !== "89a") { $fh->closeFile(); throw new Exception("Not a gif file."); } $size = array("width" => $fh->readUint16(), "height" => $fh->readUint16()); $fh->closeFile(); return $size; }
public static function dumpGif($file, $dstDir = null, $dstFilePrefix = null) { $fh = new FileHandler(); $frameCount = 0; echo "Reading '{$file}'\n"; try { $fh->openFile($file); } catch (Exception $e) { echo 'Caught exception: ', $e->getMessage(), "\n"; exit; } echo "\n\n------------------------------------------------------------------------\n"; echo "--- HEADER\n"; echo "------------------------------------------------------------------------\n\n"; $header = new Header($fh); self::dumpHeader($header); if ($header->signature !== "GIF" && $header->version !== "87a" && $header->version !== "89a") { $fh->closeFile(); throw new Exception("Not a gif file."); } $dstPath = null; if ($dstDir != null) { $dstDir = str_replace("\\", "/", $dstDir); if ($dstFilePrefix == null) { $dstFilePrefix = basename($file, '.gif'); } $lc = substr($dstDir, -1); if ("/" !== $lc) { $dstDir .= "/"; } $dstPath = $dstDir . $dstFilePrefix . "_"; } echo "\n\n------------------------------------------------------------------------\n"; echo "--- LOGICAL SCREEN DESCTIPTOR\n"; echo "------------------------------------------------------------------------\n\n"; $lsd = new LogicalScreenDescriptor($fh); self::dumpLogicalScreenDescriptor($lsd); while (!$fh->isEOF()) { switch (ord($fh->peekByte())) { case AbstractExtensionBlock::CONTROL_EXTENSION: echo "\n\n------------------------------------------------------------------------\n"; echo "--- EXTENSION BLOCK\n"; echo "------------------------------------------------------------------------\n\n"; self::dumpExtensionBlock($fh, $frameCount, $lsd, $dstPath); break; case AbstractExtensionBlock::CONTROL_IMAGE: $frameCount++; echo "\n\n------------------------------------------------------------------------\n"; echo "--- FRAME " . $frameCount . "\n"; echo "------------------------------------------------------------------------\n\n"; $idb = new ImageDescriptor($fh); self::dumpImageDescriptor($idb); self::writeFrame($dstPath, $frameCount, $lsd, $idb); break; case AbstractExtensionBlock::CONTROL_TRAILER: echo "\n\n------------------------------------------------------------------------\n"; echo "--- TRAILER FOUND - END OF IMAGE.\n"; echo "--- FRAMES " . $frameCount . "\n"; echo "------------------------------------------------------------------------\n\n"; $fh->seekForward(1); break; case AbstractExtensionBlock::CONTROL_TERMINATOR: $fh->seekForward(1); break; default: $c = $fh->readByte(); echo "\n\n------------------------------------------------------------------------\n"; echo "--- UNKNOWN CODE: 0x" . bin2hex($c) . " (" . ord($c) . ")\n"; echo "------------------------------------------------------------------------\n\n"; } } echo "\n"; $fh->closeFile(); }
/** * @param $ratio * @param LogicalScreenDescriptor $lsd * * @throws Exception */ public function resize($ratio, $lsd) { $scrLp = $this->screenLeftPos; $scrTp = $this->screenTopPos; $tFileS = tempnam("BewareOfGeeksBearingGifs", "grS"); $tFileD = tempnam("BewareOfGeeksBearingGifs", "grD"); $fhT = new FileHandler(); $fhT->openFile($tFileS, true); $fhT->writeData($this->generateGif($lsd)); $fhT->closeFile(); ImageHandler::resizeGif($tFileS, $tFileD, $ratio, true); $fhT->openFile($tFileD, false); new Header($fhT); $nLsd = new LogicalScreenDescriptor($fhT); $nId = self::getFirstImageDescriptor($fhT, $this->parentGCE); $fhT->closeFile(); unset($tFileD); unset($tFileS); $this->screenLeftPos = (int) round($scrLp * $ratio); $this->screenTopPos = (int) round($scrTp * $ratio); $this->screenWidth = $nId->screenWidth; $this->screenHeight = $nId->screenHeight; $this->reserved = $nId->reserved; $this->interlaceFlag = $nId->interlaceFlag; $this->sortFlag = $nLsd->sortFlag; $this->colorTableFlag = $nLsd->colorTableFlag; $this->colorTableSize = $nLsd->colorTableSize; $this->colorTable = $nLsd->colorTable; $this->lzwMinCodeSize = $nId->lzwMinCodeSize; $this->dataSubBlocks = $nId->dataSubBlocks; }